Dot-Net

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

  • March 18, 2010

我正在嘗試使用 WCF 建構通用 Web 服務介面,以允許第 3 方開發人員連接到我們的軟體。經過大量的努力和閱讀(這個問題很有幫助),我終於讓 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/GetDatexml、TestService.svc/json/GetDatejson 並將 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 支持<enableWebScript />。僅當您想要支持 ASP.NET AJAX 時才需要。通常,如果您嘗試使用標準腳​​本庫,您希望為您的服務啟用此支持。WebScriptEnablingBehavior

相反,您想要為 JSON 端點做的只是使用WebHttpBehavior並設置 DefaultOutgoingResponseFormat=“JSON”。問題是,在 .NET 3.5 中,您無法通過 config 控制此設置,因為WebHttpElement不會公開這些屬性以進行配置。為了在 3.5 中解決這個問題,我在另一個 StackOverflow 問題EnhancedWebHttpElement 的答案中提供了一個實現。

幸運的是,微軟意識到了這個缺點,並通過4.0WebHttpBehavior啟用了所有設置的配置。WebHttpElement

引用自:https://stackoverflow.com/questions/2471358