wcf - 自托管 WCF 服务上的 500 内部服务器错误

标签 wcf

我正在尝试开发一个使用 ServiceHost 对象托管的新 WCF 服务。我能够启动控制台应用程序,并且可以看到它通过 netstat 绑定(bind)到端口 80。使用 WireShark,我还可以看到客户端能够连接到该端口并发送数据。我很早就遇到了客户端在 SOAP 消息中发送的数据量的问题,但能够通过在绑定(bind)上设置最大接收大小来解决该问题。我得到的 HTTP 500 错误是:

由于 EndpointDispatcher 的 ContractFilter 不匹配,接收方无法处理带有 Action '' 的消息。这可能是因为合约不匹配(发送方和接收方之间的操作不匹配)或发送方和接收方之间的绑定(bind)/安全不匹配。检查发送方和接收方是否具有相同的契约(Contract)和相同的绑定(bind)(包括安全要求,例如消息、传输、无)。

以下是我的 WCF 代码和我的服务代码。

public class MyWCFService
{
    private ServiceHost _selfHost;

    public void Start()
    {
        Uri baseAddress = new Uri(@"http://192.168.1.10");

        this._selfHost = new ServiceHost(typeof(MyServiceImpl), baseAddress);

        try {
            WebHttpBinding binding = new WebHttpBinding();
            binding.MaxBufferSize = 524288;
            binding.MaxReceivedMessageSize = 524288;
            this._selfHost.AddServiceEndpoint(typeof(IMyServiceContract), binding, "MyService");

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            this._selfHost.Description.Behaviors.Add(smb);

            this._selfHost.Open();
        }
        catch ( CommunicationException ce ) {
            this._selfHost.Abort();
        }
    }

    public void Stop()
    {
        this._selfHost.Close();
    }
}

以下是我的服务契约(Contract)。它相当简单,只有一个操作。预计它将在收到基于 SOAP 的消息时调用。
[ServiceContract(Namespace = "http://www.exampe.com")]
public interface IMyServiceContract
{
    [OperationContract (Action="http://www.example.com/ReportData", ReplyAction="*")]
    string ReportData( string strReport );
}

以下是我对服务契约(Contract)的执行情况
class MyServiceImpl : IMyServiceContract
{
    public string ReportData( string strReport )
    {
        return "ok";
    }
}

这是我从我的客户那里得到的(strReport 很长,所以我排除了它)
POST /MyService HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.example.com/ReportData"
Host: 192.168.1.10
Content-Length: 233615
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ReportData xmlns="http://www.example.com/">
            <strReport>
                ........
            </strReport>
        </ReportData>
    </soap:Body>
</soap:Envelope>

任何解决此问题的帮助将不胜感激。

问候,
理查德

最佳答案

您希望您的服务是 SOAP 服务还是 REST 服务?

在服务端,它被配置为 REST 服务(因为您使用的是 WebHttpBinding)。但是,来自您的客户端的请求是一个 SOAP 请求。如果您的客户端是 WCF 客户端,它可能正在使用 wsHttpBinding 或 basicHttpBinding。这两个都是针对 SOAP 的。

您可以:

  • 更改您的服务以使用 basicHttpBinding 或 wsHttpBindding 来匹配您的客户端(如果您想使用 SOAP),或
  • 将您的客户端更改为使用 webHttpBinding(如果您想使用 REST)。这将需要更多更改,因为您的操作契约(Contract)未正确归因于 REST。无论如何,WCF 不是 REST 的好选择。 ASP.Net Web API 更简单并且得到更好的支持。


  • 您的操作契约(Contract)中指定的 Action 应该只是 ReportData 而不是命名空间限定的版本。事实上,您可能根本不需要它。
  • 您可以删除 ReplyAction(如果您的客户需要,也可以指定适当的值)

  • 通常,您不需要指定这些。我不是 SOAP 内部的专家,但我相信如果您不指定这些值,WCF 会根据方法名称指定这些值。 .Net 中方法名称的唯一性将确保在这种情况下操作/回复操作是唯一的。

    有了这些更改,它可以在我的机器上运行 (TM)

    关于wcf - 自托管 WCF 服务上的 500 内部服务器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18135278/

    相关文章:

    c# - 使用 DataContract 类的 BinaryFormatter 有问题吗?

    wcf - WebHttpBinding 未到达客户端

    wcf - WCF可靠 session 的目的是什么?

    c# - 如何判断我运行的是哪个 WCF 版本?

    c# - 如何从程序集/WCF 服务内部访问程序集版本和名称?

    jquery - 在 JQuery 中解析 JSON 对象

    c# - Windows服务之间如何通信

    c# - 使用 WCF 通过线路传输最少量的数据

    c# - WCF 服务导出 1 个接口(interface)和 2 个实现类

    java - 从 WCF 和 Biztalk 中的 WSDL 导入键/值复杂类型定义