WCF hizmeti için REST / SOAP uç noktaları


425

WCF hizmetim var ve hem RESTfull hizmeti hem de SOAP hizmeti olarak göstermek istiyorum. Daha önce böyle bir şey yapan var mı?


iyi soru ve harika cevaplar.
chandra rv

Yanıtlar:


584

Hizmeti iki farklı uç noktada açığa çıkarabilirsiniz. SOAP, SOAP'ı destekleyen bağlamayı kullanabilir, örneğin basicHttpBinding, RESTful, webHttpBinding kullanabilir. REST hizmetinizin JSON'da olacağını varsayıyorum, bu durumda, iki davranış noktasını aşağıdaki davranış yapılandırmasıyla yapılandırmanız gerekir

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

Senaryonuzdaki uç nokta yapılandırmasının bir örneği

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

yani, hizmet şu adreste satışa sunulacak:

RESTful yapmak için işlem sözleşmesine [WebGet] uygulayın. Örneğin

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

REST hizmeti JSON'da değilse, işlem parametrelerinin karmaşık tür içeremeyeceğini unutmayın.

SOAP ve RESTful POX (XML) için yazıyı yanıtla

Dönüş biçimi olarak düz eski XML için, bu hem SOAP hem de XML için çalışan bir örnektir.

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

REST Plain Eski XML için POX davranışı

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

Endpoints

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

Hizmet şu adreste satışa sunulacak:

REST isteği tarayıcıda deneyin,

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

Hizmet referansını ekledikten sonra SOAP hizmeti için SOAP istek istemcisi uç noktası yapılandırması,

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

C # 'da

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

Bunu yapmanın bir başka yolu, iki farklı hizmet sözleşmesi ve her biri belirli bir yapılandırmaya sahip olmaktır. Bu, kod düzeyinde bazı kopyalar oluşturabilir, ancak günün sonunda, çalışmasını sağlamak istersiniz.


11
IIS'de someserver / myvirtualdir / service.svc gibi bazı sanal dizinlerde barındırdığımda bu nasıl görünüyor ? Nasıl erişmeliyim?
Sunny Milenov

Bu bir adım daha ileri almak ve JSON adresi için HTTPS bir bağlama eklemek istiyorum. Bunu nasıl yaparım? stackoverflow.com/questions/18213472/…
Steve

Hizmet Arabirim'e başvurmaya çalıştığımda sözleşme IEvents'ım geçersiz diyor: <service name = "Events"> <endpoint address = "json" bağlama = "webHttpBinding" behaviorConfiguration = "jsonBehavior" contract = "IEvents" />. IEvents benim arabirimde bir [ServiceContract] özniteliği vardır, bu yüzden neden emin değilim. </service>
PositiveGuy

Alabilirim 44652 / MyResource / json: localhost işe ama iş için bir id alamayan localhost: 44652 / MyResource / 98 / json . "/ {İd}" adlı bir UriTemplate eklemeyi denedim, "events / {id} 'yi de denedim ama hizmete girmeye çalıştığımda bulamıyorum. Sadece ilk işler, ikincisini nasıl alacağımdan emin değilim işe.
PositiveGuy

2
Orada fiziksel bir dosya olmadan nasıl çalışabilir? Sadece 404 hataları alıyorum gibi görünüyor, bir şey eksik olmalı
RoboJ1M

39

Bu mesaj "Toplum wiki" ile zaten çok iyi bir cevabı vardır ve ben de Rick Strahl'ın Web Blog bakmak tavsiye, gibi WCF istirahat hakkında çok iyi mesajlar vardır bu .

Her ikisi de bu tür MyService-hizmet almak için kullanılır ... Sonra jQuery REST arabirimi veya Java SOAP kullanabilirsiniz.

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

Ve bu benim hizmet sınıfım (.svc-codebehind, arayüz gerekmez):

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

Aslında sadece Json veya Xml kullanıyorum ama ikisi de demo amaçlı. Bunlar veri almak için GET istekleridir. Veri eklemek için özniteliklere sahip bir yöntem kullanırdım:

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

Bu WebGet ve WebInvoke özniteliklerini ekleyerek elde edeceğiniz faydaları düşündüğünüzü merak ediyorum.
Darrel Miller

2
Tarayıcı ile istekte bulunabilirsiniz: localhost / MyService.svc / MyXmlResource / test Ve açıkça Json veya Xml biçimini söyleyin. Aynı yöntemlerin her ikisine de yanıt vermesini istiyorsanız, işte bir bağlantı: blogs.msdn.com/dotnetinterop/archive/2008/11/04/…
Tuomas Hietanen

Bu test amaçlıdır. Sadece uç noktalarınızın çalışıp çalışmadığını görmek için. SoapUI'ya baktın mı? soapui.org
Darrel Miller

@TuomasHietanen - WebHttp davranışını kullanarak JSON türü yanıt almıyorum ancak enableWebScript kullanarak JSON türü yanıt alıyorum. ResponseFormat'ı WebMessageFormat.Json olarak koydum. Öte yandan enableWebScript davranışı kullanırsam URItemplate kullanamıyorum. Herhangi bir fikir?
smile.al.d.way

1
@CoffeeAddict - Neden inteface kullanmalısınız? Sadece arayüze mi ihtiyacınız var? Bu arayüzü asla tekrar kullanmayacaksınız. Bu daha basit.
Tuomas Hietanen

25

Yalnızca tek bir web hizmeti geliştirmek ve birçok farklı uç noktada (yani SOAP + REST, XML, JSON, CSV, HTML çıktıları) barındırılmasını istiyorsanız. Ayrıca , geliştirdiğiniz her hizmetin herhangi bir yapılandırma gerektirmeden hem SOAP hem de REST uç noktalarında otomatik olarak kullanıma hazır olduğu tam olarak bu amaç için oluşturduğum ServiceStack'ı kullanmayı da düşünmelisiniz .

Merhaba Dünya sadece (hiçbir yapılandırma gerekli) ile hizmet ile basit nasıl oluşturulacağını örnek gösterir:

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

Başka bir yapılandırmaya gerek yoktur ve bu hizmet şu anda REST ile kullanılabilir:

Ayrıca , hizmetlerinizin çıktısını daha iyi görselleştirebilmeniz için kolay bir HTML çıktısıyla ( Accept: text / html örneğin bir tarayıcıya sahip bir HTTP istemcisi ile çağrıldığında) yerleşik olarak gelir .

Farklı REST fiillerinin kullanımı da önemsizdir, işte C # 1 sayfasında (WCF'yi yapılandırmak için gerekenden daha az;) tam bir REST hizmeti CRUD uygulaması:


7

MSDN'nin bunun için bir makalesi var gibi görünüyor:

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

tanıtım:

Varsayılan olarak, Windows Communication Foundation (WCF) uç noktaları yalnızca SOAP istemcileri için kullanılabilir hale getirir. Nasıl yapılır: Temel WCF Web HTTP Hizmeti Oluşturma'da, SOAP olmayan istemciler için bir uç nokta kullanılabilir. Bir Web uç noktası ve bir SOAP uç noktası olarak aynı sözleşmeyi her iki şekilde de kullanılabilir kılmak istediğiniz zamanlar olabilir. Bu konuda bunun nasıl yapılacağı ile ilgili bir örnek gösterilmektedir.


3

Davranış yapılandırmasını REST bitiş noktasına tanımlamalıyız

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

ve ayrıca bir servise

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

Davranışlardan sonra, bir sonraki adım ciltlemelerdir. İçin örnek basicHttpBinding için SABUN için son nokta ve WebHttpBinding DİNLENME .

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

Son olarak servis tanımında 2 uç noktayı tanımlamalıyız. Nereye REST hizmetine gerek yok, uç nokta adres "" "dikkat.

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

Hizmetin arabiriminde işlemi öznitelikleriyle tanımlıyoruz.

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

Tüm taraflara katılmak, bu bizim WCF sistemimiz olacaktır. HizmetModel tanımı.

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

Bitiş noktası hem test etmek için, kullanabilir WCFClient için SABUN ve PostMan için DİNLENME .


Beklendiği gibi çalışıyor
Shiv

0

İşe yaraması için yaptığım şey bu. Uç nokta davranışının içine
webHttp automaticFormatSelectionEnabled = "true" değerini koyduğunuzdan emin olun .

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

İç servis modeli

   <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 Davranışı

  <endpointBehaviors>
    <behavior name="jsonBehavior">
      <webHttp automaticFormatSelectionEnabled="true"  />
      <!-- use JSON serialization -->
    </behavior>
  </endpointBehaviors>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.