WCFサービスのREST / SOAPエンドポイント


425

WCFサービスがあり、それをRESTfullサービスとSOAPサービスの両方として公開したい。誰かが以前にこのようなことをしたことがありますか?


良い質問と素晴らしい答え。
chandra rv

回答:


584

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にない場合、操作のパラメーターに複合型を含めることはできません。

SOAPおよびRESTful POX(XML)の投稿への返信

戻り形式としてのプレーンな古い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リクエスト はブラウザーで試してください。

http://www.example.com/xml/accounts/A123

サービス参照を追加した後の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つの異なるサービスコントラクトを公開し、それぞれに特定の構成を設定することです。これにより、コードレベルでいくつかの重複が生成される可能性がありますが、結局のところ、それを機能させる必要があります。


11
someserver / myvirtualdir / service.svcのような仮想ディレクトリのIISで.svcをホストしている場合、これはどのように見えますか?どうすればアクセスできますか?
サニーミレノフ2011

これをさらに一歩進めて、JSONアドレスのHTTPSへのバインディングを追加したいと思います。それ、どうやったら出来るの? stackoverflow.com/questions/18213472/...
スティーブ

サービスインターフェイスを参照しようとすると、コントラクトのIEventsが無効であると言われています:<service name = "Events"> <endpoint address = "json" binding = "webHttpBinding" behaviorConfiguration = "jsonBehavior" contract = "IEvents" />。私のIEventsはインターフェイスに[ServiceContract]属性を持っているので、その理由はわかりません。</ service>
PositiveGuy

私は得ることができます44652 / myresourceで/ JSON:localhostの仕事に私は仕事へのidを取得することはできませんローカルホスト:44652 / myresourceで/ 98 / JSONを。「/ {id}」のUriTemplateを追加しようとしましたが、「events / {id}」も試しましたが、サービスにアクセスしようとしても見つかりません。最初の方法のみが機能し、後者の取得方法がわかりません仕事へ。
PositiveGuy

2
物理ファイルがない状態でどのように機能しますか?私は404エラーが発生するようですが、何かが欠けているに違いありません
RoboJ1M '

39

この投稿には既に「コミュニティウィキ」による非常に良い回答があり、リックストラールのウェブブログもご覧になることをお勧めします。このような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){
    //...

これらのWebGet属性とWebInvoke属性を追加することで、どのようなメリットが得られると思いますか。
Darrel Miller

2
ブラウザでリクエストを行うことができます: localhost / MyService.svc / MyXmlResource / test そして、フォーマットJsonまたはXmlを明示的に言います。あなたは同じ方法で両方を応答する場合は、ここでのリンクは次のとおりです。 blogs.msdn.com/dotnetinterop/archive/2008/11/04/...
のTuomas Hietanen

これはテスト用です。エンドポイントが機能しているかどうかを確認するだけです。SoapUIを見たことがありますか? soapui.org
Darrel Miller

@TuomasHietanen-webHttp動作を使用してJSONタイプの応答を取得しませんが、enableWebScriptを使用してJSONタイプの応答を取得します。ResponseFormatをWebMessageFormat.Jsonとして配置しました。一方、enableWebScript動作を使用すると、URItemplateを使用できません。何か案は?
smile.al.d.way、2011年

1
@CoffeeAddict-なぜインターフェースを使用する必要があるのですか?インターフェースを持っているだけですか?このインターフェースを再利用することはありません。これはもっと簡単です。
Tuomas Hietanen 2013年

25

単一の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の構成にかかる時間よりも短いです)。


7

MSDNにはこのための記事があるようです:

https://msdn.microsoft.com/en-us/library/bb412196(v=vs.110).aspx

イントロ:

既定では、Windows Communication Foundation(WCF)は、エンドポイントをSOAPクライアントのみが使用できるようにします。「方法:基本的なWCF Web HTTPサービスを作成する」では、非SOAPクライアントがエンドポイントを利用できるようにしています。同じエンドポイントをWebエンドポイントとSOAPエンドポイントの両方で利用できるようにしたい場合があります。このトピックでは、これを行う方法の例を示します。


3

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>

両方のエンドポイントをテストするには、WCFClientSOAPにPostManRESTに使用できます。


期待どおりに機能する
Shiv

0

これは私がそれを機能させるためにやったことです。エンドポイントの動作内に
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>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.