WCF REST中的SOAP头错误

5
我遇到了这个错误:
“IService”合同中的“GetFields”操作使用具有SOAP标头的MessageContract。 None MessageVersion不支持SOAP标头。
问题在于我的操作被两个端点使用:具有messageVersion =“Soap12WSAddressing10”的CustomEndpoint和第二个webHttpBehavior。
我认为这个错误是由Rest使用MessageVersion.None引起的问题。
有没有解决方法?
3个回答

3
很遗憾,在WCF中RESTfulness往往是一个契约级别的特性。这意味着您通常不能在非RESTful上下文中使用RESTful契约,反之亦然。
在这里您有两个选择,每个选择都有其权衡。首先,您可以拥有两个单独的契约(一个用于RESTful功能和一个“普通”的非RESTful契约),它们都由您的WCF服务实现。这要求两个契约具有相同的方法签名,这可能并不总是可能的。
第二个选择是拥有两个单独的WCF服务,每个服务都有自己的契约和处理代码,但是它们都将操作调用转移到它们都知道的第三个类中,该类执行实际工作。这是最灵活的解决方案,但往往需要特殊的翻译代码才能在一个或两个WCF服务中调用第三个类。

2

您不需要提供不同的接口和/或实现服务类。

如果您正在使用尝试通过OperationContext使用XXMessageHeaders的行为代码,则必须编写代码来检查标头上的MessageVersion是否为MessageVersion.None,并改用WebOperationContext(来自System.ServiceModel.Web)。

我有一个使用相同接口和相同实现服务类的工作示例。

 <services>            
    <service name="ExampleService" behaviorConfiguration="MyServiceBehavior">
        <endpoint name="ExampleService.BasicHttpBinding"
                  binding="basicHttpBinding"
                  contract="IExampleService"
                  address="" />

        <endpoint name="ExampleService.WebHttpBinding"
                  binding="webHttpBinding"
                  contract="IExampleService"
                  address="restful"   
                  behaviorConfiguration="webHttpRestulBehavior"    />
    </service>
</services>

<behaviors>
  <endpointBehaviors>

    <behavior name="webHttpRestulBehavior">
      <webHttp/> 
    </behavior>

  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceMetadata httpGetEnabled="true"  />
    </behavior>
  </serviceBehaviors>
</behaviors>

假设 .svc 文件名为 Example.svc,在 IIS 中的终结点 URL 为:"http://hostname:port/Example.svc",对于 WCF 和 Rest,分别为:
- WCF:无需更改 URL。 - Rest:终结点 URL 为:"http://hostname:port/Example.svc/restful/"。

1

当我尝试合并两个服务时,我遇到了与此相同的异常;一个使用SOAP端点,另一个使用REST端点。

我认为问题在于WCF似乎不喜欢在ServiceContract中看到使用MessageContract的操作和REST操作。所以我解决这个问题的方法是将合同分成两部分,然后仅让REST端点实现WebGet操作,如下所示:

[ServiceContract]
public interface IExampleSoapService : IExampleRestService
{
    [OperationContract]
    void SomeSoapOperation(ExampleMessageContract message);
}

[ServiceContract]
public interface IExampleRestService
{
    [OperationContract]
    [WebGet(UriTemplate = "/{id}", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    void SomeRestOperation(int id);
}

然后在配置中:

<services>            
    <service name="ExampleService">
        <endpoint name="ExampleService.BasicHttpBinding"
                  binding="basicHttpBinding"
                  contract="IExampleSoapService"
                  address="soap" />
        <endpoint name="ExampleService.WebHttpBinding"
                  binding="webHttpBinding"
                  contract="IExampleRestService" />
    </service>
</services>

当我像这样拆分合同时,问题似乎消失了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接