3

我最近将 WCF SOAP 服务转换为 REST/JSON 服务。如此处的响应中所述,Visual Studio 的添加服务引用功能无法为 JSON 服务生成代码。该问题答案中的链接文章暗示了将 WCF 暴露为 REST 和 SOAP 来解决问题的可能性,但它没有提供任何详细信息。

有谁知道这是否可行,如果可以,如何设置?

总是有自己编写代码生成器的替代方案,它读取 WCF REST 服务的 WSDL 并生成 C# 类,但似乎应该有比这更简单的解决方案。

作为参考,我的 web.config:

<system.serviceModel>
<behaviors>
  <endpointBehaviors>
    <behavior name="RestBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="GetBehavior" >
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug
         httpHelpPageEnabled="true"
         includeExceptionDetailInFaults="true"
      />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <webHttpBinding>
    <binding name="WebHttpBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="None" />
      </security>
    </binding>
  </webHttpBinding>
</bindings>
<services>
  <service name="Service" behaviorConfiguration="GetBehavior">
    <endpoint address=""
      binding="webHttpBinding"
      behaviorConfiguration="RestBehavior"
      contract="IService"
      bindingConfiguration="WebHttpBinding">
    </endpoint>
  </service>
</services>
</system.serviceModel>

我的服务方法都具有以下属性:

[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
4

2 回答 2

2

有可能,您需要创建两个端点:一个用于soap,另一个用于json。我在我的项目中已经这样做了,并且可以通过 SoapUI 或 Fiddler (json) 同时访问服务,这是示例配置:

<system.serviceModel>
 <behaviors>
  <serviceBehaviors>
   <behavior name="BehaviourService">
    <serviceMetadata httpGetEnabled="true" />
     <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
      <behavior name="BehaviourWebHttp">
        <webHttp  defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="True" faultExceptionEnabled="True" />
      </behavior>
  </endpointBehaviors>
</behaviors>

<services>
  <service name="NameSpace.MyService" behaviorConfiguration="BehaviourService" >
    <endpoint address ="soap" binding="basicHttpBinding" contract="NameSpace.IMyService"></endpoint>
    <endpoint binding="webHttpBinding" behaviorConfiguration="BehaviourWebHttp" contract="NameSpace.IMyService" ></endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:7689/MyService.svc"/>
      </baseAddresses>
    </host>
  </service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

还要让你的合同看起来像:

[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "MyMethod", Method = "POST")]
bool MyMethod();

然后您可以通过“localhost:7689/MyService.svc?wsdl”和 JSON 通过“localhost:7689/MyService.svc/MyMethod”访问 SOAP

于 2014-05-28T11:53:36.717 回答
0

据我所知,您有三个选项可以组合来自 WCF 的 json 和 xml 响应,但它们都不是可取的:

  1. 为 XML 和 JSON 编写特定的方法(和端点)并相应地装饰它们
  2. 连接到序列化引擎并将其与accept来自 http 请求的标头检查相结合。
  3. 让您的方法接受并返回一个Stream 按照惯例告诉 WCF 让您直接访问请求和响应流的方法。

每种方法都有自己的缺陷: 1. 这很丑陋并且与 Rest 的想法相反,因为序列化应该使用 http 标头而不是 URL(应该标识资源)来确定。2.附加到序列化引擎很复杂,仍然需要查看标题以确定序列化。3. 您在映射请求参数方面没有任何帮助,并且序列化使您的方法体变得混乱。

我已经多次使用方法3,因为它简单易上手,但方法2似乎更正确。

于 2013-07-21T21:45:56.937 回答