WCF REST错误中的SOAP标头

时间:2011-11-02 15:40:00

标签: wcf wcf-rest

3 个答案:

答案 0 :(得分:2)

不幸的是,在WCF中,RESTfulness往往是契约级功能。这意味着您通常无法在非RESTful上下文中使用RESTful合同,反之亦然。

这里有两个选项,每个都有自己的权衡。首先,您可以拥有两个单独的合同(一个标记为RESTful功能,另一个标记为“简单”,非RESTful合同),这两个合同都由WCF服务实现。这要求两个合同都具有相同的方法签名,这可能并不总是可行的。

第二个选项是拥有两个单独的WCF服务,每个服务都有自己的合同和处理代码,但是要让它们将操作调用卸载到第三个类,它们都知道实际的工作。这是最灵活的解决方案,但往往需要在(或两者)WCF服务中使用特殊的转换代码才能调用第三类。

答案 1 :(得分:1)

您不必提供不同的界面和/或实现服务类。

如果您在尝试通过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://主机名:端口/ Example.svc”

用于WCF

for Rest:

  

“HTTP://主机名:端口/ Example.svc /宁静/”

答案 2 :(得分:0)

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

我认为问题在于WCF似乎不喜欢在相同的 MessageContract中看到使用ServiceContract作为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>

我将这样的合同分开,问题似乎消失了。