共同學習了前面一些概念,終於開始正題了哈。RESTful的Web Service調用直觀,返回的內容容易解析。這里先會描述一個簡單的場景--Web Service提供一個方法來搜索個人信息,傳入人名,返回完整個人信息。
下面我們一步步用WCF實現一個RESTful的Web Service。在這之后分別描述用普通Console程序host在本地,以及用IIS發布到網絡。
1. Contract
namespace WcfRESTful
{
[ServiceContract]
public interface IPersonRetriever
{
[OperationContract]
[WebGet(UriTemplate = "Persons/{name}", ResponseFormat = WebMessageFormat.Json)]
Person GetPerson(string name);
}
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public DateTime Birthday { get; set; }
}
}
這里需要注意的是在方法GetPerson()上面的WebGetAttribute:
1.1 WebGetAttribute定義了該方法的訪問方式為RESTful的Get(關於RESTful可以參考本小博中關於REST介紹的文章)。
1.2 UriTemplet描述了URL匹配的格式,當格式匹配時,{name}位置的字符串會被對應傳入為方法參數。
1.3 ResponseFormat指定了返回的數據格式,可選項為JSON和XML。
2. Contract實現
namespace WcfRESTful
{
public class PersonRetriever : IPersonRetriever
{
public Person GetPerson(string name)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
return new Person { Name = name, Age = 22, Birthday = DateTime.Now };
}
}
}
這個實現里面,我們簡單的返回一個用傳入名參數為name的Person實例。這里補充一點:如果ContectType是"Text",如果返回結果串包含特別字符(比如轉義,雙引號,XML文件片段等),有些情況會在IE中解析不正常,造成字段缺失,目前沒有找到相關資料說明IE解析規則。為了方便和謹慎起見,直接用"text/plain"。
3. 在Console中Host Service
在第1,2步的基礎上,我們開始在console中host這個service。
namespace WcfRESTful
{
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://127.0.0.1:9998/PersonRetriever");
using (ServiceHost host = new ServiceHost(typeof(PersonRetriever), baseAddress))
{
WebHttpBinding binding = new WebHttpBinding();
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IPersonRetriever), binding, baseAddress);
WebHttpBehavior httpBehavior = new WebHttpBehavior();
endpoint.Behaviors.Add(httpBehavior);
host.Opened += delegate
{
Console.WriteLine("Hosted successfully.");
};
host.Open();
Console.ReadLine();
}
}
}
}
讓后我們通過URL:http://127.0.0.1:9998/PersonRetriever/Persons/Tom 就可以訪問該Service了,其中"Tom"是需要查詢的人名。在IE中輸入該URL,回車之后的結果如下圖:
4. 在IIS中Host Web Service
4.1新建一個WCF Service(或者Web Service依.Net Framework版本不同而定)工程,把第1,2步的Contract和實現Copy到App_Code文件夾下面。
4.2修改Service.svc - 注意,Factory="System.ServiceModel.Activation.WebServiceHostFactory"必須添加才可以直接在IE查看結果,但是Matedata將被屏蔽不能顯示。
<%@ ServiceHost Language="C#" Debug="true" Service="WcfRESTful.PersonRetriever" CodeBehind="~/App_Code/PersonRetriever.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>
4.3添加Endpoint到Web.config
<system.serviceModel>
<services>
<service name="WcfRESTful.PersonRetriever" behaviorConfiguration="ServiceBehavior">
<endpoint binding="webHttpBinding" contract="WcfRESTful.IPersonRetriever"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
4.4添加工程目錄到IIS虛擬路徑,命名為WCFTest。
以上4.1-4.4的所有步驟都完成了,我們通過URL:http://16X.19X.18X.6X/wcftest/Service.svc/Persons/Tom 一樣可以得到上面的結果{"Age":22,"Birthday":"\/Date(1329226087212-0500)\/","Name":"Tom"}。
這里需要補充一點,在4.1步驟,我們新建一個Web Service工程,僅僅是為了少寫一些Web.Config的配置(會默認有system.web,complier等配置信息),其實我們完全可以新建App_Code文件夾,把Contact和Contract實現拷入該文件夾,然后在外層手工新建Service.svc,Web.config並寫入相應配內容,一樣可以成功部署和使用。
5. 總結
RESTful Web Service用更簡單通用的協議(HTTP,少了SOAP這一道封裝和解析),更直接的結果,讓人眼前一亮,在資源不需要交互邏輯和復雜結構的情況下還是不錯的選擇。