Я пытаюсь создать общий интерфейс веб-сервиса с помощью WCF, чтобы позволить сторонним разработчикам подключаться к нашему программному обеспечению. После долгих боев и чтения (этот вопрос помог много), я, наконец, объединил 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 не работает.
Единственная другая вещь, которую я видел, которая, как я думаю, будет работать, заключается в создании трех разных сервисов (файлы .svc), которые все реализуют интерфейс, который указывает контракт, но в классах указывается разные атрибуты WebGet/WebInvoke для каждого класса, Это похоже на большую дополнительную работу, что, честно говоря, я не понимаю, почему структура не справляется для меня. Реализация классов будет одинаковой, за исключением атрибутов, что означает, что со временем было бы легко, чтобы ошибки/изменения были исправлены/выполнены в одной реализации, но не в других, что приводило к непоследовательному поведению при использовании JSON vs Например, реализация SOAP.
Я делаю что-то неправильно здесь? Я принимаю совершенно неправильный подход и злоупотребляю WCF? Есть лучший способ сделать это?
С моим опытом работы с веб-материалами, я думаю, что для какой-то структуры это должно быть возможно, и я даже имею в голове мысль о том, как его построить. Похоже, что WCF должен делать это, и я действительно не хочу изобретать велосипед.