【问题标题】:JSON and SOAP WCF Service?JSON 和 SOAP WCF 服务?
【发布时间】:2013-07-21 21:28:01
【问题描述】:

我最近将 WCF SOAP 服务转换为 REST/JSON 服务。如响应 here 中所述,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)]

【问题讨论】:

  • 客户端和服务解决方案是否可以共享同一个“模型”项目? (模型 == 数据合同)

标签: .net json wcf rest soap


【解决方案1】:

有可能,您需要创建两个端点:一个用于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"

【讨论】:

    【解决方案2】:

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

    1. 为 XML 和 JSON 编写特定的方法(和端点)并相应地装饰它们
    2. 挂钩到serialization engine 并将其与来自http 请求的accept 标头的检查结合起来。
    3. 让您的方法接受并返回Stream which by convention tells WCF to give you direct access to the request and response streams

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      相关资源
      最近更新 更多