使用UriTemplate在WCF中组合SOAP/JSON/XML

gre*_*mac 25 .net rest wcf soap web-services

我正在尝试使用WCF构建一个通用的Web服务接口,以允许第三方开发人员加入我们的软件.经过多次努力和阅读(这个问题有很多帮助),我终于让SOAP,JSON和XML(POX)一起工作了.

为了简化,这里是我的代码(为了使这个例子简单,我没有使用接口 - 我确实尝试了这两种方式):

<ServiceContract()> _
Public Class TestService
    Public Sub New()
    End Sub

    <OperationContract()> _
    <WebGet()> _
    Public Function GetDate() As DateTime
        Return Now
    End Function


    '<WebGet(UriTemplate:="getdateoffset/{numDays}")> _
    <OperationContract()> _
    Public Function GetDateOffset(ByVal numDays As Integer) As DateTime
        Return Now.AddDays(numDays)
    End Function

End Class
Run Code Online (Sandbox Code Playgroud)

和web.config代码:

<services>
  <service name="TestService" 
           behaviorConfiguration="TestServiceBehavior">
    <endpoint address="soap" binding="basicHttpBinding" contract="TestService"/>
    <endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="TestService"/>
    <endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="TestService"/>
    <endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding" />
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="jsonBehavior">
      <enableWebScript/>
    </behavior>
    <behavior name="poxBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="TestServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
Run Code Online (Sandbox Code Playgroud)

这实际上是有效的 - 我可以转到TestService.svc/xml/GetDatexml,TestService.svc/json/GetDate用于json,并指向SOAP客户端TestService.svc?wsdl并使SOAP查询工作.

我想解决的部分是查询.我必须使用TestService.svc/xml/GetDateOffset?numDays=4而不是TestService.svc/xml/GetDateOffset/4.如果我指定UriTemplate,我会收到错误:

Endpoints using 'UriTemplate' cannot be used with 'System.ServiceModel.Description.WebScriptEnablingBehavior'.

但当然没有使用<enableWebScript/>,JSON不起作用.

我认为唯一可行的另一件事是制作3种不同的服务(.svc文件),它们都实现了一个指定契约的接口,但在类中为每个类指定了不同的WebGet/WebInvoke属性.这似乎是很多额外的工作,坦率地说,我不明白为什么框架不适合我.除了属性之外,类的实现都是相同的,这意味着随着时间的推移,错误/更改很容易在一个实现中得到修复/完成而不是其他实现,导致使用JSON vs时行为不一致例如,SOAP实现.

我在这里做错了吗?我采取了完全错误的方法并滥用WCF吗?有一个更好的方法吗?

根据我在做web内容的经验,我认为应该可以使用某种框架来处理这个问题......我甚至对如何构建它有一个想法.看起来WCF似乎应该这样做,我真的不想重新发明轮子.

Dre*_*rsh 26

其实<enableWebScript />不是需要"纯" JSON支持.的WebScriptEnablingBehavior,如果你想支持ASP.NET AJAX时,才需要.通常,如果您尝试使用标准脚本库,则不希望为您的服务启用此支持.

相反,您要为JSON端点做的只是使用WebHttpBehavior并设置DefaultOutgoingResponseFormat ="JSON".问题是,在.NET 3.5中,您无法通过配置来控制此设置,因为WebHttpElement不会公开这些属性以进行配置.要解决此3.5已经提供了对我所说的实现EnhancedWebHttpElement 在这里这样的回答另一个问题StackOverflow上.

幸运的是,微软意识到了这个缺点,并WebHttpBehavior通过WebHttpElement4.0中的所有设置进行了配置.