使用 UriTemplate 在 WCF 中组合 SOAP/JSON/XML
Posted
技术标签:
【中文标题】使用 UriTemplate 在 WCF 中组合 SOAP/JSON/XML【英文标题】:Combined SOAP/JSON/XML in WCF, using UriTemplate 【发布时间】:2011-01-29 02:32:14 【问题描述】:我正在尝试使用 WCF 构建通用 Web 服务接口,以允许第 3 方开发人员连接到我们的软件。经过一番努力和阅读(this question 帮助很大),我终于让 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
和 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>
这确实有效 - 我可以转到 TestService.svc/xml/GetDate
获取 xml,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?有一个更好的方法吗?
以我在网络方面的经验,我认为某种 类的框架应该可以处理这个问题......我什至对如何构建它有了一个想法。看起来 WCF 应该这样做,我真的不想重新发明***。
【问题讨论】:
您的代码示例非常有帮助!我只有 JSON 绑定,发现我无法使用 .net 应用程序中的服务,所以这正是我所追求的! :) 请注意,我认为现在 ASP.NET Web API 已经完全过时了;导致这个问题被问到的代码早就用 Web API 重写了。我强烈建议不要使用 WCF,除非你是 stuck in the dark ages and really need SOAP。 【参考方案1】:实际上,<enableWebScript />
不是“纯”JSON 支持所必需的。仅当您想要支持 ASP.NET AJAX 时才需要 WebScriptEnablingBehavior
。通常,如果您尝试使用标准脚本库,您不希望为您的服务启用此支持。
您想要为 JSON 端点做的只是使用 WebHttpBehavior
并设置 DefaultOutgoingResponseFormat="JSON"。问题是,在 .NET 3.5 中,您无法通过 config 控制此设置,因为 WebHttpElement
不会公开这些属性以进行配置。为了在 3.5 中解决这个问题,我为另一个 *** 问题提供了我称之为 EnhancedWebHttpElement
here in this answer 的实现。
幸运的是,Microsoft 意识到了这个缺点,并通过WebHttpElement
in 4.0 启用了所有WebHttpBehavior
设置的配置。
【讨论】:
【参考方案2】:Drew 的回答是正确的,但我认为问题仍然存在。有没有一种理智的方式来为 AJAX () 提供 JSON 和 UriTemplate 的祝福?
我认为值得一提的是,返回的 JSON 与使用 [WebGet(ResponseFormat=WebMessageFormat.Json)] 生成的 JSON 不同。前者包裹在 MS AJAX 'd' 元素上,例如"d":[...]。
【讨论】:
【参考方案3】:您在操作中指定了整数参数。 URI 模板不适用于 int 参数。请把它改成字符串,它会工作。
我认为您必须编写自己的 QuerystringConverter 才能将 int 与 URITemplate 一起使用。
【讨论】:
以上是关于使用 UriTemplate 在 WCF 中组合 SOAP/JSON/XML的主要内容,如果未能解决你的问题,请参考以下文章