寫在前面
公司有個項目,需要和sharepoint集成,用到了restful,在網上查了一下,wcf方式來實現,還是很方便的,就采用了這種方式,至於web api,沒研究過,由於接口急着用,就采用wcf了,用起來也比較順手。
概念
什么是rest?
REST 描述了一個架構樣式的互聯系統(如 Web 應用程序)。REST 約束條件作為一個整體應用時,將生成一個簡單、可擴展、有效、安全、可靠的架構。由於它簡便、輕量級以及通過 HTTP 直接傳輸數據的特性,RESTful Web 服務成為基於 SOAP 服務的一個最有前途的替代方案。用於 web 服務和動態 Web 應用程序的多層架構可以實現可重用性、簡單性、可擴展性和組件可響應性的清晰分離。開發人員可以輕松使用 Ajax 和 RESTful Web 服務一起創建豐富的界面。
REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是 RESTful。
一個例子
新建一個wcf項目。代碼如下:
契約
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. [ServiceContract] public interface IUserService { /// <summary> /// 獲得所有的用戶信息 /// </summary> /// <returns>json或者xml</returns> [OperationContract] [WebGet(UriTemplate = "api/query", ResponseFormat = WebMessageFormat.Xml)] List<UserInfo> QueryList(); /// <summary> /// 根據id查詢用戶信息 /// </summary> /// <param name="id"></param> /// <returns></returns> [OperationContract] [WebGet(UriTemplate = "api/querybyid/{id}", ResponseFormat = WebMessageFormat.Json)] UserInfo Query(string id); /// <summary> /// 根據名字查詢 /// </summary> /// <param name="name"></param> /// <returns></returns> [OperationContract] [WebInvoke(UriTemplate = "api/querybyname/{name}", Method = "GET", ResponseFormat = WebMessageFormat.Xml)] UserInfo QueryByName(string name); /// <summary> /// 根據編號刪除用戶信息 /// </summary> /// <param name="id"></param> /// <returns></returns> [OperationContract] [WebInvoke(UriTemplate = "api/delete/{id}", Method = "DELETE", ResponseFormat = WebMessageFormat.Xml)] bool Delete(string id); /// <summary> /// 添加用戶信息 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> [OperationContract] [WebInvoke(UriTemplate = "api/add", Method = "POST", ResponseFormat = WebMessageFormat.Xml)] bool Insert(UserInfo userInfo); /// <summary> /// 更新用戶信息 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> [OperationContract] [WebInvoke(UriTemplate = "api/modify", Method = "PUT", ResponseFormat = WebMessageFormat.Xml)] bool Update(UserInfo userInfo); }
服務
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together. // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging. public class UserService : IUserService { /// <summary> /// 獲得所有的用戶信息 /// </summary> /// <returns>json或者xml</returns> public List<UserInfo> QueryList() { return new List<UserInfo>() { new UserInfo() { ID = 1, Name = "wofly", Age = 22, Birthday = DateTime.Now, Gender = true }, new UserInfo() { ID = 2, Name = "san zhang", Age = 21, Birthday = DateTime.Now, Gender = true }, new UserInfo() { ID = 3, Name = "wukong sun", Age = 23, Birthday = DateTime.Now, Gender = false }, new UserInfo() { ID = 4 Name = "zi ma", Age = 45, Birthday = DateTime.Now, Gender = true } }; } /// <summary> /// 根據id查詢用戶信息 /// </summary> /// <param name="id"></param> /// <returns></returns> public UserInfo Query(string id) { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } var users = QueryList(); int iId = Convert.ToInt32(id); return users.Where(x => x.ID == iId).FirstOrDefault(); } /// <summary> /// 根據編號刪除用戶信息 /// </summary> /// <param name="id"></param> /// <returns></returns> public bool Delete(string id) { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } //當前操作上下文 WebOperationContext woc = WebOperationContext.Current; //狀態碼 woc.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK; try { var users = QueryList(); int iId = Convert.ToInt32(id); var user = users.Where(x => x.ID == iId).FirstOrDefault(); return users.Remove(user); } catch (Exception ex) { throw ex; } } /// <summary> /// 添加用戶信息 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> public bool Insert(UserInfo userInfo) { throw new NotImplementedException(); } /// <summary> /// 更新用戶信息 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> public bool Update(UserInfo userInfo) { throw new NotImplementedException(); } /// <summary> /// 根據名字查詢 /// </summary> /// <param name="name"></param> /// <returns></returns> public UserInfo QueryByName(string name) { var users = QueryList(); return users.Where(x => x.Name.Equals(name)).FirstOrDefault(); } }
用戶信息類
/// <summary> /// 用戶信息類 /// </summary> [DataContract] public class UserInfo { /// <summary> /// 編號 /// </summary> [DataMember] public int ID { set; get; } /// <summary> /// 名字 /// </summary> [DataMember] public string Name { set; get; } /// <summary> /// 性別 /// </summary> [DataMember] public bool Gender { set; get; } /// <summary> /// 年齡 /// </summary> [DataMember] public int Age { set; get; } /// <summary> /// 生日 /// </summary> [DataMember] public DateTime Birthday { set; get; } }
通過 WCF 4.0 里創建的 WCF Service Application 發布REST服務很簡單,只需要在 svc 的 Markup 里加上 Factory:
原
<%@ ServiceHost Language="C#" Debug="true" Service="Wolfy.WCFRestfuleDemo.UserService" CodeBehind="UserService.svc.cs" %>
修改后
<%@ ServiceHost Language="C#" Debug="true" Service="Wolfy.WCFRestfuleDemo.UserService" CodeBehind="UserService.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>
修改前,瀏覽svc服務
修改后
注意:UriTemplate 路徑段的變量類型必須為“字符串”。
修改后,瀏覽svc服務
到這里,你應該發現了,WCF的Metadata不能訪問了,也就說不能訪問svc的wsdl了。
測試
在瀏覽器中輸入:http://localhost:21074/UserService.svc/api/query
到這里已經成功了,那么我們訪問一下id為1用戶信息
http://localhost:21074/UserService.svc/api/querybyid/1
{"Age":22,"Birthday":"\/Date(1433419746141+0800)\/","Gender":true,"ID":1,"Name":"wofly"}
路由方式訪問
看到上面的url,很像mvc的路由,那有沒有辦法修改成路由訪問方式呢?答案是肯定的。只需在全局處理程序中注冊路由就可以了。
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { //注冊路由 System.Web.Routing.RouteTable.Routes.Add( new System.ServiceModel.Activation.ServiceRoute( "userInfo", new System.ServiceModel.Activation.WebServiceHostFactory(), typeof(UserService) )); } }
使用注冊的路由訪問服務
http://localhost:21074/userInfo/api/query
總結
這里實現了restful風格的wcf的查詢操作,關於增刪改(post,delete,put)將在后面的文章中說明。
參考文章:
http://blog.csdn.net/fangxing80/article/details/6235662