ฉันมีบริการ WCF และฉันต้องการให้เป็นบริการ RESTfull และเป็นบริการ SOAP ใครเคยทำสิ่งนี้มาก่อนบ้าง
ฉันมีบริการ WCF และฉันต้องการให้เป็นบริการ RESTfull และเป็นบริการ SOAP ใครเคยทำสิ่งนี้มาก่อนบ้าง
คำตอบ:
คุณสามารถแสดงบริการในสองปลายทางที่แตกต่างกัน SOAP หนึ่งสามารถใช้การเชื่อมที่สนับสนุน SOAP เช่น basicHttpBinding, RESTful หนึ่งสามารถใช้ webHttpBinding ฉันคิดว่าบริการ REST ของคุณจะอยู่ใน JSON ในกรณีนั้นคุณต้องกำหนดค่าจุดปลายสองจุดด้วยการกำหนดค่าลักษณะการทำงานต่อไปนี้
<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 พารามิเตอร์ของการดำเนินการต้องไม่มีชนิดที่ซับซ้อน
สำหรับ XML เก่าธรรมดาเป็นรูปแบบการส่งคืนนี่เป็นตัวอย่างที่ใช้งานได้ทั้งกับ SOAP และ XML
[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate = "accounts/{id}")]
Account[] GetAccount(string id);
}
พฤติกรรม POX สำหรับ REST Plain Old XML
<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 ลองใช้ในเบราว์เซอร์
การ กำหนดค่าจุดสิ้นสุดไคลเอนต์คำขอ 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");
อีกวิธีในการดำเนินการคือการเปิดเผยสัญญาบริการที่แตกต่างกันสองสัญญาและแต่ละรายการมีการกำหนดค่าเฉพาะ สิ่งนี้อาจทำให้เกิดการซ้ำซ้อนในระดับรหัสอย่างไรก็ตามในตอนท้ายของวันคุณต้องการทำให้มันใช้งานได้
โพสต์นี้มีอยู่แล้วคำตอบที่ดีมากด้วย "วิกิพีเดียชุมชน" และผมก็ขอแนะนำให้ไปดูที่ริกราล์เว็บบล็อกที่มีการโพสต์ดีมากเกี่ยวกับ WCF ส่วนที่เหลือเช่นนี้
ฉันใช้ทั้งสองเพื่อรับ MyService-service ชนิดนี้ ... จากนั้นฉันสามารถใช้ส่วนต่อประสาน REST จาก jQuery หรือ SOAP จาก Java
นี่คือจากเว็บของฉันกำหนดค่า:
<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){
//...
หากคุณต้องการพัฒนาบริการเว็บเดียวและให้บริการพื้นที่บนปลายทางที่แตกต่างกัน (เช่น SOAP + REST ด้วย XML, JSON, CSV, HTML outputes) คุณควรพิจารณาใช้ServiceStackซึ่งฉันได้สร้างขึ้นเพื่อจุดประสงค์นี้ที่บริการทุกอย่างที่คุณพัฒนานั้นจะมีให้โดยอัตโนมัติทั้งบน SOAP และ REST endpoints แบบไม่ต้องมีการกำหนดค่าใด ๆ
ตัวอย่าง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 ที่เป็นมิตร (เมื่อเรียกด้วยไคลเอนต์ HTTP ที่ยอมรับ: text / htmlเช่นเบราว์เซอร์) เพื่อให้คุณสามารถเห็นภาพผลลัพธ์ของบริการได้ดียิ่งขึ้น
การจัดการคำกริยา REST ที่แตกต่างกันนั้นมีความสำคัญเช่นกันนี่คือแอป RUD บริการที่สมบูรณ์ใน 1 หน้าของ C # (น้อยกว่าที่จะใช้ในการกำหนดค่า WCF;):
MSDN ดูเหมือนจะมีบทความในตอนนี้:
https://msdn.microsoft.com/en-us/library/bb412196(v=vs.110).aspx
บทนำ:
ตามค่าเริ่มต้น Windows Communication Foundation (WCF) ทำให้จุดสิ้นสุดพร้อมใช้งานสำหรับไคลเอ็นต์ SOAP เท่านั้น ในวิธีการ: สร้างบริการเว็บ HTTP พื้นฐานของ WCF จุดสิ้นสุดจะพร้อมใช้งานสำหรับไคลเอ็นต์ที่ไม่ใช่ SOAP อาจมีบางครั้งที่คุณต้องการให้สัญญาเดียวกันพร้อมใช้งานทั้งสองวิธีเป็นจุดสิ้นสุดของเว็บและเป็นจุดสิ้นสุดของ SOAP หัวข้อนี้แสดงตัวอย่างของวิธีการทำเช่นนี้
เราจะต้องกำหนดค่าพฤติกรรมที่ปลายทาง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 จุดสิ้นสุดในข้อกำหนดบริการ ให้ความสนใจกับที่อยู่ = "" ของจุดสิ้นสุดซึ่งไม่จำเป็นต้องใช้บริการ 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>
<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>
ในการทดสอบทั้งปลายทางเราสามารถใช้WCFClientเพื่อSOAPและPostManเพื่อREST
นี่คือสิ่งที่ฉันทำเพื่อให้มันใช้ได้ ตรวจสอบให้แน่ใจว่าคุณใส่
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>