WCFサービスがあり、それをRESTfullサービスとSOAPサービスの両方として公開したい。誰かが以前にこのようなことをしたことがありますか?
WCFサービスがあり、それをRESTfullサービスとSOAPサービスの両方として公開したい。誰かが以前にこのようなことをしたことがありますか?
回答:
2つの異なるエンドポイントでサービスを公開できます。SOAPはSOAPをサポートするバインディング(basicHttpBindingなど)を使用でき、RESTfulはwebHttpBindingを使用できます。RESTサービスはJSONであると想定しています。その場合、2つのエンドポイントを次の動作構成で構成する必要があります。
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
シナリオのエンドポイント構成の例は次のとおりです
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="ITestService"/>
</service>
</services>
したがって、サービスは
[WebGet]を操作コントラクトに適用してRESTfulにします。例えば
public interface ITestService
{
[OperationContract]
[WebGet]
string HelloWorld(string text)
}
RESTサービスがJSONにない場合、操作のパラメーターに複合型を含めることはできません。
戻り形式としてのプレーンな古いXMLの場合、これはSOAPとXMLの両方で機能する例です。
[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate = "accounts/{id}")]
Account[] GetAccount(string id);
}
RESTプレーンオールドXMLのPOX動作
<behavior name="poxBehavior">
<webHttp/>
</behavior>
エンドポイント
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/>
</service>
</services>
サービスはで利用可能になります
RESTリクエスト はブラウザーで試してください。
サービス参照を追加した後のSOAPサービスのSOAP要求クライアントエンドポイント構成
<client>
<endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
contract="ITestService" name="BasicHttpBinding_ITestService" />
</client>
C#で
TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");
これを行う別の方法は、2つの異なるサービスコントラクトを公開し、それぞれに特定の構成を設定することです。これにより、コードレベルでいくつかの重複が生成される可能性がありますが、結局のところ、それを機能させる必要があります。
この投稿には既に「コミュニティウィキ」による非常に良い回答があり、リックストラールのウェブブログもご覧になることをお勧めします。このようなWCF Restに関する良い投稿がたくさんあります。
この種類のMyServiceサービスを取得するために両方を使用しました...次に、jQueryからのRESTインターフェースまたはJavaからのSOAPを使用できます。
これは私のWeb.Configからです:
<system.serviceModel>
<services>
<service name="MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint name="rest" address="" binding="webHttpBinding" contract="MyService" behaviorConfiguration="restBehavior"/>
<endpoint name="mex" address="mex" binding="mexHttpBinding" contract="MyService"/>
<endpoint name="soap" address="soap" binding="basicHttpBinding" contract="MyService"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
そして、これは私のサービスクラスです(.svc-codebehind、インターフェースは必要ありません):
/// <summary> MyService documentation here ;) </summary>
[ServiceContract(Name = "MyService", Namespace = "http://myservice/", SessionMode = SessionMode.NotAllowed)]
//[ServiceKnownType(typeof (IList<MyDataContractTypes>))]
[ServiceBehavior(Name = "MyService", Namespace = "http://myservice/")]
public class MyService
{
[OperationContract(Name = "MyResource1")]
[WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "MyXmlResource/{key}")]
public string MyResource1(string key)
{
return "Test: " + key;
}
[OperationContract(Name = "MyResource2")]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource/{key}")]
public string MyResource2(string key)
{
return "Test: " + key;
}
}
実際にはJsonまたはXmlのみを使用していますが、これらは両方ともデモ目的でここにあります。これらは、データを取得するためのGETリクエストです。データを挿入するには、属性を持つメソッドを使用します。
[OperationContract(Name = "MyResourceSave")]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource")]
public string MyResourceSave(string thing){
//...
単一のWebサービスのみを開発し、それを多くの異なるエンドポイント(つまり、SOAP + REST、XML、JSON、CSV、HTML出力付き)でホストする場合。また、この目的のために私が作成したServiceStackを使用することも検討してください。開発したすべてのサービスは、設定を必要とせずに、SOAPエンドポイントとRESTエンドポイントの両方で自動的に利用できます。
Hello Worldだけ(何の設定は必要ありません)とサービスとシンプルを作成する方法の例を示しています:
public class Hello {
public string Name { get; set; }
}
public class HelloResponse {
public string Result { get; set; }
}
public class HelloService : IService
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
他の設定は必要ありません。このサービスはRESTですぐに利用できます。
また、フレンドリーなHTML出力(Accept:text / htmlを備えたHTTPクライアントで呼び出された場合はブラウザーなど)が組み込まれているため、サービスの出力をより視覚的に視覚化できます。
さまざまなREST動詞の処理も簡単です。C#の1ページにある完全なRESTサービスCRUDアプリを次に示します(WCFの構成にかかる時間よりも短いです)。
MSDNにはこのための記事があるようです:
https://msdn.microsoft.com/en-us/library/bb412196(v=vs.110).aspx
イントロ:
既定では、Windows Communication Foundation(WCF)は、エンドポイントをSOAPクライアントのみが使用できるようにします。「方法:基本的なWCF Web HTTPサービスを作成する」では、非SOAPクライアントがエンドポイントを利用できるようにしています。同じエンドポイントをWebエンドポイントとSOAPエンドポイントの両方で利用できるようにしたい場合があります。このトピックでは、これを行う方法の例を示します。
RESTエンドポイントに動作構成を定義する必要があります
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
</behavior>
</endpointBehaviors>
そしてまたサービスへ
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
動作の後、次のステップはバインディングです。たとえば、basicHttpBindingからSOAPエンドポイントへ、webHttpBindingからRESTへ。
<bindings>
<basicHttpBinding>
<binding name="soapService" />
</basicHttpBinding>
<webHttpBinding>
<binding name="jsonp" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
最後に、サービス定義で2つのエンドポイントを定義する必要があります。エンドポイントのaddress = ""に注意してください。RESTサービスを行う必要はありません。
<services>
<service name="ComposerWcf.ComposerService">
<endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="ComposerWcf.Interface.IComposerService" />
<endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="ComposerWcf.Interface.IComposerService" />
<endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
</service>
</services>
サービスのインターフェースでは、属性で操作を定義します。
namespace ComposerWcf.Interface
{
[ServiceContract]
public interface IComposerService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/autenticationInfo/{app_id}/{access_token}", ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
Task<UserCacheComplexType_RootObject> autenticationInfo(string app_id, string access_token);
}
}
すべてのパーティに参加すると、これがWCF system.serviceModel定義になります。
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="soapService" />
</basicHttpBinding>
<webHttpBinding>
<binding name="jsonp" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="ComposerWcf.ComposerService">
<endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="ComposerWcf.Interface.IComposerService" />
<endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="ComposerWcf.Interface.IComposerService" />
<endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
両方のエンドポイントをテストするには、WCFClientをSOAPに、PostManをRESTに使用できます。
これは私がそれを機能させるためにやったことです。エンドポイントの動作内に
webHttp automaticFormatSelectionEnabled = "true"を配置してください。
[ServiceContract]
public interface ITestService
{
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/product", ResponseFormat = WebMessageFormat.Json)]
string GetData();
}
public class TestService : ITestService
{
public string GetJsonData()
{
return "I am good...";
}
}
インサイドサービスモデル
<service name="TechCity.Business.TestService">
<endpoint address="soap" binding="basicHttpBinding" name="SoapTest"
bindingName="BasicSoap" contract="TechCity.Interfaces.ITestService" />
<endpoint address="mex"
contract="IMetadataExchange" binding="mexHttpBinding"/>
<endpoint behaviorConfiguration="jsonBehavior" binding="webHttpBinding"
name="Http" contract="TechCity.Interfaces.ITestService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8739/test" />
</baseAddresses>
</host>
</service>
エンドポイントの動作
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp automaticFormatSelectionEnabled="true" />
<!-- use JSON serialization -->
</behavior>
</endpointBehaviors>