我正在尝试使用 WCF 构建通用 Web 服务接口(interface),以允许第 3 方开发人员连接到我们的软件。经过大量的努力和阅读(this question 帮助很大),我终于让 SOAP、JSON 和 XML (POX) 一起工作。
为了简化,这是我的代码(为了使这个例子简单,我没有使用接口(interface)——我确实尝试过这两种方式):
<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 文件),它们都实现了一个指定契约(Contract)的接口(interface),但在类中为每个类指定不同的 WebGet/WebInvoke 属性。这似乎是很多额外的工作,坦率地说,我不明白为什么框架不能为我处理。除了属性之外,类的实现都是相同的,这意味着随着时间的推移,错误/更改很容易在一个实现中得到修复/完成,而在其他实现中则不然,导致使用 JSON vs 时的行为不一致例如 SOAP 实现。
我在这里做错了吗?我是否采取了完全错误的方法并滥用了 WCF?有一个更好的方法吗?
以我从事网络工作的经验,我认为某种框架应该可以处理这个问题……我什至对如何构建它有了一个想法。看起来 WCF 应该这样做,我真的不想重新发明轮子。
请您参考如下方法:
其实<enableWebScript />
“纯” JSON 支持不需要。 WebScriptEnablingBehavior
仅当您想要支持 ASP.NET AJAX 时才需要。通常,如果您尝试使用标准脚本库,您不希望为您的服务启用此支持。
相反,您想要为 JSON 端点做的只是使用 WebHttpBehavior
并设置 DefaultOutgoingResponseFormat="JSON"。问题是,在 .NET 3.5 中,您无法通过配置控制此设置,因为 WebHttpElement
不公开这些属性进行配置。为了在 3.5 中解决这个问题,我提供了一个我称之为 EnhancedWebHttpElement
的实现。 here in this answer到另一个 StackOverflow 问题。
幸运的是,微软意识到了这个缺点并启用了所有 WebHttpBehavior
的配置。通过 WebHttpElement
in 4.0 设置.