436 Stimmen

REST / SOAP Endpunkte für einen WCF-Dienst

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

1 Stimmen

Gute Frage und tolle Antworten.

593voto

Ray Lu Punkte 25327

Sie können den Dienst an zwei verschiedenen Endpunkten bereitstellen. Der SOAP-Endpunkt kann die Bindung verwenden, die SOAP unterstützt, z. B. basicHttpBinding, der RESTful-Endpunkt kann die webHttpBindung verwenden. Ich nehme an, dass Ihr REST-Dienst in JSON sein wird. 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>

Der Dienst wird also verfügbar sein unter

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

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

Hinweis: Wenn der REST-Dienst nicht in JSON vorliegt, können die Parameter der Vorgänge keinen komplexen Typ enthalten.

Antwort auf den Beitrag 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 funktionieren würde.

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

POX-Verhalten für REST Einfaches 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 Dienst wird verfügbar sein unter

REST-Anfrage versuchen Sie es im Browser,

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

SOAP-Anfrage Client-Endpunktkonfiguration für den SOAP-Dienst nach Hinzufügen der Dienstreferenz,

  <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 besteht darin, zwei verschiedene Dienstverträge mit jeweils spezifischer Konfiguration bereitzustellen. Dies kann zu einigen Duplikaten auf Code-Ebene führen, aber am Ende des Tages wollen Sie ja, dass es funktioniert.

12 Stimmen

Wie sieht das aus, wenn ich die .svc in IIS in einem virtuellen Verzeichnis wie someserver/meinvirtualdir/service.svc ? Wie soll ich darauf zugreifen?

0 Stimmen

Ich möchte noch einen Schritt weiter gehen und eine Bindung an HTTPS für die JSON-Adresse hinzufügen. Wie kann ich das tun? stackoverflow.com/questions/18213472/

0 Stimmen

Es sagt, dass mein Vertrag IEvents ungültig ist, wenn ich versuche, meine Service-Schnittstelle zu verweisen: <service name="Events"> <endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="IEvents"/>. Mein IEvents hat ein [ServiceContract]-Attribut auf der Schnittstelle, also bin ich nicht sicher, warum. </service>

40voto

Tuomas Hietanen Punkte 4060

Dieser Beitrag hat bereits eine sehr gute Antwort von "Community wiki" und ich empfehle auch einen Blick auf Rick Strahl's Web Blog, dort gibt es viele gute Beiträge über WCF Rest wie ce .

Ich habe beide verwendet, um diese Art von MyService-Service zu erhalten... 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 dies ist meine Serviceklasse (.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 verwende ich nur Json oder Xml, aber diese beiden sind hier für einen Demo-Zweck. Das sind GET-Anfragen, um Daten zu erhalten. Um Daten einzufügen, würde ich eine Methode mit Attributen verwenden:

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

0 Stimmen

Ich bin neugierig zu erfahren, welche Vorteile Sie durch das Hinzufügen dieser WebGet- und WebInvoke-Attribute zu erzielen glauben.

2 Stimmen

Sie können Anfragen per Browser stellen: localhost/MyService.svc/MyXmlResource/test Und sagen Sie ausdrücklich Format Json oder Xml. Wenn Sie dieselben Methoden wollen, um beide zu beantworten, hier ist ein Link: blogs.msdn.com/dotnetinterop/archive/2008/11/04/

0 Stimmen

Dies ist für Testzwecke. Nur um zu sehen, ob Ihre Endpunkte funktionieren. Haben Sie sich SoapUI angeschaut? soapui.org

25voto

mythz Punkte 138304

Wenn Sie nur einen einzigen Webdienst entwickeln und diesen auf vielen verschiedenen Endpunkten hosten lassen wollen (z. B. SOAP + REST, mit XML-, JSON-, CSV-, HTML-Ausgaben). Sie sollten auch die Verwendung von ServiceStack die ich für genau diesen Zweck entwickelt habe, bei dem jeder von Ihnen entwickelte Dienst automatisch sowohl auf SOAP- als auch auf REST-Endpunkten verfügbar ist, ohne dass eine Konfiguration erforderlich ist.

Le site Hallo Welt Beispiel zeigt, wie man einen einfachen Dienst mit nur (keine Konfiguration erforderlich) erstellt:

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

Es ist keine weitere Konfiguration erforderlich, und dieser Dienst ist sofort mit REST in verfügbar:

Außerdem ist er mit folgenden Funktionen ausgestattet eine freundliche HTML-Ausgabe (beim Aufruf mit einem HTTP-Client, der über Akzeptieren:text/html z.B. einen Browser), damit Sie den Output Ihrer Dienste besser visualisieren können.

Der Umgang mit verschiedenen REST-Verben ist ebenso trivial, hier ist eine komplette REST-Service-CRUD-Anwendung in 1 Seite C# (weniger als es dauern würde, WCF zu konfigurieren ;):

7voto

FMFF Punkte 1588

MSDN scheint jetzt einen Artikel zu diesem Thema zu haben:

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

Intro:

Windows Communication Foundation (WCF) stellt Endpunkte standardmäßig nur für SOAP-Clients zur Verfügung. In How to: Erstellen eines einfachen WCF-Web-HTTP-Dienstes wird ein Endpunkt für Nicht-SOAP-Clients verfügbar gemacht. Es kann vorkommen, dass Sie denselben Vertrag sowohl als Web- als auch als SOAP-Endpunkt zur Verfügung stellen möchten. In diesem Thema wird ein Beispiel dafür gezeigt, wie dies geschehen kann.

3voto

Jailson Evora Punkte 166

Wir müssen die Verhaltenskonfiguration definieren, um REST Endpunkt

<endpointBehaviors>
  <behavior name="restfulBehavior">
   <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
  </behavior>
</endpointBehaviors>

und auch zu einer Dienstleistung

<serviceBehaviors>
   <behavior>
     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
   </behavior>
</serviceBehaviors>

Nach den Verhaltensweisen folgt der nächste Schritt: die Bindungen. Zum Beispiel basicHttpBinding an SOAP Endpunkt und webHttpBinding zu REST .

<bindings>
   <basicHttpBinding>
     <binding name="soapService" />
   </basicHttpBinding>
   <webHttpBinding>
     <binding name="jsonp" crossDomainScriptAccessEnabled="true" />
   </webHttpBinding>
</bindings>

Schließlich müssen wir die 2 Endpunkte in der Dienstdefinition definieren. Achtung für die Adresse="" des Endpunktes, wo zu REST-Dienst ist nicht notwendig nichts.

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

In der Schnittstelle des Dienstes definieren wir die Operation mit ihren Attributen.

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

Dies wird unsere WCF system.serviceModel-Definition sein, die alle Parteien verbindet.

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

Um die beiden Endpunkte zu testen, können wir WCFClient a SOAP y PostMan a REST .

0 Stimmen

Funktioniert erwartungsgemäß gut

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X