wcf - tutorial - windows communication foundation




REST/SOAP-Endpunkte für einen WCF-Dienst (4)

Das habe ich getan, damit es funktioniert. Stellen Sie sicher, dass Sie setzen
webHttp automaticFormatSelectionEnabled = "true" innerhalb des Endpunktverhaltens.

[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...";
    }
}

Inside-Service-Modell

   <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>

EndPoint-Verhalten

  <endpointBehaviors>
    <behavior name="jsonBehavior">
      <webHttp automaticFormatSelectionEnabled="true"  />
      <!-- use JSON serialization -->
    </behavior>
  </endpointBehaviors>

Ich habe einen WCF-Dienst und möchte ihn sowohl als RESTfull-Dienst als auch als SOAP-Dienst verfügbar machen. Hat jemand schon einmal so etwas gemacht?


Dieser Beitrag hat bereits eine sehr gute Antwort von "Community Wiki" und ich empfehle auch Rick Strahls Web Blog zu lesen, es gibt viele gute Posts über WCF Rest this .

Ich habe beides verwendet, um diese Art von MyService-Service zu bekommen ... Dann kann ich die REST-Schnittstelle von jQuery oder SOAP von Java verwenden.

Dies ist von meiner 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>

Und das ist meine Service-Klasse (.svc-codebehind, keine Schnittstellen erforderlich):

    /// <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;
    }
}

Eigentlich benutze ich nur Json oder Xml, aber diese beiden sind hier für einen Demo-Zweck. Das sind GET-Requests um Daten zu bekommen. Um Daten einzufügen, würde ich Methode mit Attributen verwenden:

[OperationContract(Name = "MyResourceSave")]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource")]
public string MyResourceSave(string thing){
    //...

Sie können den Dienst an zwei verschiedenen Endpunkten verfügbar machen. Im SOAP kann man die Bindung verwenden, die SOAP unterstützt, zB basicHttpBinding, im RESTful kann man das webHttpBinding verwenden. Ich nehme an, dass sich Ihr REST-Service in JSON befindet. In diesem Fall müssen Sie die beiden Endpunkte mit der folgenden Verhaltenskonfiguration konfigurieren

<endpointBehaviors>
  <behavior name="jsonBehavior">
    <enableWebScript/>
  </behavior>
</endpointBehaviors>

Ein Beispiel für die Endpunktkonfiguration in Ihrem Szenario ist

<services>
  <service name="TestService">
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="json" binding="webHttpBinding"  behaviorConfiguration="jsonBehavior" contract="ITestService"/>
  </service>
</services>

Also, der Service wird verfügbar sein bei

Wenden Sie [WebGet] auf den Operationsvertrag an, um RESTful zu machen. z.B

public interface ITestService
{
   [OperationContract]
   [WebGet]
   string HelloWorld(string text)
}

Hinweis: Wenn der REST-Service nicht in JSON ist, dürfen die Parameter der Operationen keinen komplexen Typ enthalten.

Antwort auf den Post für SOAP und RESTful POX (XML)

Für einfaches altes XML als Rückgabeformat ist dies ein Beispiel, das sowohl für SOAP als auch für XML funktioniert.

[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
    [OperationContract]
    [WebGet(UriTemplate = "accounts/{id}")]
    Account[] GetAccount(string id);
}

POX-Verhalten für REST Plain Old XML

<behavior name="poxBehavior">
  <webHttp/>
</behavior>

Endpunkte

<services>
  <service name="TestService">
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="xml" binding="webHttpBinding"  behaviorConfiguration="poxBehavior" contract="ITestService"/>
  </service>
</services>

Der Service wird verfügbar sein unter

REST-Anfrage versuche es im Browser,

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

SOAP-Anfrage- Client-Endpunktkonfiguration für SOAP-Service nach dem Hinzufügen der Service-Referenz,

  <client>
    <endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
      contract="ITestService" name="BasicHttpBinding_ITestService" />
  </client>

in C #

TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");

Eine andere Möglichkeit, dies zu tun, besteht darin, zwei unterschiedliche Serviceverträge und jeweils eine bestimmte Konfiguration bereitzustellen. Dies kann einige Duplikate auf Code-Ebene generieren, aber am Ende des Tages wollen Sie es zum Laufen bringen.


Wenn Sie nur einen einzigen Web-Service entwickeln und ihn auf vielen verschiedenen Endpunkten (SOAP + REST, mit XML, JSON, CSV, HTML-Ausgang) hosten möchten. Sie sollten auch ServiceStack verwenden, den ich für genau diesen Zweck entwickelt habe, bei dem jeder von Ihnen entwickelte Dienst automatisch auf SOAP- und REST-Endpunkten ohne zusätzliche Konfiguration verfügbar ist.

Das Hello World- Beispiel zeigt, wie man ein einfaches mit service mit nur erstellen (keine Konfiguration erforderlich):

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 };
    }
}

Keine andere Konfiguration ist erforderlich, und dieser Service ist sofort verfügbar mit REST in:

Es wird auch mit einer freundlichen HTML-Ausgabe eingebaut (wenn es mit einem HTTP-Client aufgerufen wird, der Accept: text / html, zB einen Browser, hat), so dass Sie die Ausgabe Ihrer Dienste besser visualisieren können.

Der Umgang mit verschiedenen REST-Verben ist ebenso trivial. Hier ist eine vollständige CRUD-App für den REST-Service auf 1 Seite von C # (weniger als für die Konfiguration von WCF erforderlich;):





soap