建立一個既支援WSDL又支援REST的WCFWebService
首先回顧一下REST,WCF和WebService這三個基本概念。
REST:REST最核心的概念是“資源”,一個uri代表一個特定的資源。使用它的一個好處就是用戶端只需要發送一個簡單的http包即可動作伺服器的資源,沒有了SOAP協議包的複雜,以至於使用Javascript就可以輕鬆的調用REST的服務。
WCF:它是一個分布式應用的開發架構,它整合了.Net平台下所有的和分布式系統有關的技術,如Enterprise Sevices(COM+).Net Remoting、Web Service(ASMX)、WSE3.0和MSMQ訊息佇列。
WebService:它是行業標準,也就是Web Service 規範,它不是某一個架構或者技術。微軟的WebService架構就是ASP.NET WebService。它是使用SOAP協議進行資料互動的,需要提供wsdl檔案來描述該WebService的介面。
當前有很多的開發環境提供了對WebService調用的支援,比如,在VS.net環境只需要添加個Web引用,就可以在本地產生一個和WebService對應的代理類,本地只需要使用該代理類就可以與WebService進行互動,完全感覺不到SOAP協議的存在。但是,如果想在JavaScript中使用WebService就會比較費事了,因為需要封裝一個SOAP XML的資料包。那麼,有沒有一個既提供WSDL檔案供開發環境組建代理程式類,又可以在JavaScript中通過傳遞一個簡單的Json字串就可以輕鬆調用的WebService呢?當然,那就是本文需要做。
1、在VS2010中建立一個預設的WcfService項目,專案檔的一覽如下。
這就是一個簡單的WebService了。現在把該WebService發布到IIS中,發布後WcfService的URL為http://192.168.2.249:8084/Service1.svc。然後建立一個WinForm程式引用該WebService並調用其中的GetData方法,如
下面需要做的就是讓該WcfService支援RESTful的格式對外提供服務。
2、為Service1類型添加AspNetCompatibilityRequirementsAtribute聲明
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Service1 : IService1 { public string GetData(string value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += " Suffix"; } return composite; } }
3、修改IService1介面,使其支援JSON格式
[ServiceContract] public interface IService1 { [OperationContract] [WebInvoke(Method = "GET", UriTemplate = "GetData/?value={value}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] //使用JSON格式請求和應答 string GetData(string value); [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "GetDataUsingDataContract", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] //使用JSON格式請求和應答 CompositeType GetDataUsingDataContract(CompositeType composite); }
4、為WcfService添加一個Global.asax檔案,並註冊一個路由轉換器
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { RegisterRoutes(); } private void RegisterRoutes() { // Edit the base address of Service1 by replacing the "Service1" string below RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1))); } }
5、修改web.config檔案,添加URL路由模組,開啟AspNet相容模式和添加一個standardEndpoint節點。
<?xml version="1.0" encoding="utf-8"?><configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/> <!--開啟aspnet相容模式--> <!--添加一個standardEndpoints節點--> <standardEndpoints> <webHttpEndpoint> <!-- Configure the WCF REST service base address via the global.asax.cs file and the default endpoint via the attributes on the <standardEndpoint> element below --> <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/> </webHttpEndpoint> </standardEndpoints> </system.serviceModel> <system.webServer> <!--添加一個URL路由模組--> <modules runAllManagedModulesForAllRequests="true"> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </modules> </system.webServer> </configuration>
到此,一個既支援WSDL和RESTful的WebService已經完成。
下面分別適用Soap調用和Rest調用進行測試。
測試一:在建立的WinForm工程中調用該WebService的GetDataUsingDataContract
介面(通過抓包分析,這種調用方式採用的是SOAP方式,詳細分析請參考上篇文章http://blog.csdn.net/zztfj/article/details/7012252 )。
測試二:在RESTClient用戶端工具中使用REST請求方式調用該WebService的GetDataUsingDataContract介面
把Content-Type設定為text/json; charset=utf-8的時候,請求和應答的截屏如下:
把Content-Type設定為text/xml; charset=utf-8的時候,請求和應答的截屏如下: