WCF hizmetim var ve hem RESTfull hizmeti hem de SOAP hizmeti olarak göstermek istiyorum. Daha önce böyle bir şey yapan var mı?
WCF hizmetim var ve hem RESTfull hizmeti hem de SOAP hizmeti olarak göstermek istiyorum. Daha önce böyle bir şey yapan var mı?
Yanıtlar:
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.
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,
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.
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){
//...
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ı:
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.
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 .
İş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>