MVC4 WebAPI(一)
不管是因为什么原因,结果是在新出的MVC中,增加了WebAPI,用于提供 REST风格的WebService,个人比较喜欢REST风格的WebService,感觉比SOAP要轻量级一些,而且对客户端的要求也更少,更符合网络数据传输的一般模式,客户端完全摆脱了代理和管道来直接和WebService进行交互,具体的区别可以参见Web 服务编程,REST 与 SOAP (一)环境准备 本机的环境是XP+VS2010,需要安装VS2010 SP1升级包,MVC4升级包,Vs2010安装SP1后会影响SQLServer2008的自动提示功能,需要在安装补丁或插件,安装成功后可以新建如下的 MVC WebAPI 项目 (二)概览 新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models,Views,Controllers等文件夹和Global.asax文件
(三)Models 和WCF中的数据契约形成鲜明对比的是,MVC WebAPI中的Model就是简单的POCO,没有任何别的东西,如,你可以创建如下的Model public class TestUseMode { public string ModeKey{get;set;} public string ModeValue { get; set; } } 注意:Model必须提供public的属性,用于json或xml反序列化时的赋值 (四)Controllers MVC WebAPI中的Controllers和普通MVC的Controllers类似,不过不再继承于Controller,而改为继承API的 ApiController,一个Controller可以包含多个Action,这些Action响应请求的方法与Global中配置的路由规则有关,在后面结束Global时统一说明 (五)Global 默认情况下,模板自带了两个路由规则,分别对应于WebAPI和普通MVC的Web请求,默认的WebAPI路由规则如下 1 routes.MapHttpRoute( 2 name: "DefaultApi",3 routeTemplate: "api/{controller}/{id}",4 defaults: new { id = RouteParameter.Optional } 5 );
可以看到,默认路由使用的固定的api作为Uri的先导,按照微软官方的说法,用于区分普通Web请求和WebService的请求路径:
可以看到,默认的路由规则只指向了Controller,没有指向具体的Action,因为默认情况下,对于Controller中的Action的匹配是和Action的方法名相关联的: 具体来说,如果使用上面的路由规则,对应下面的Controller: public class TestController : ApiController { public static List<TestUseMode> allModeList = new List<TestUseMode>(); public IEnumerable<TestUseMode> GetAll() { return allModeList; } public IEnumerable<TestUseMode> GetOne(string key) { return allModeList.FindAll((mode) => { if (mode.ModeKey.Equals(key)) return true; return false; }); } public bool PostNew(TestUseMode mode) { allModeList.Add(mode); return true; } public int Delete(string key) { return allModeList.RemoveAll((mode) => { if (mode.ModeKey == key) return true; return false; }); } public int DeleteAll() { return allModeList.RemoveAll((mode) => { return true; }); } public int PutOne(string key,string value) { List<TestUseMode> upDataList = allModeList.FindAll((mode) => { if (mode.ModeKey == key) return true; return false; }); foreach(var mode in upDataList) { mode.ModeValue = value; } return upDataList.Count; } }
则,会有下面的对应关系: function getAll() { $.ajax({ url: "api/Test/",type: 'GET',success: function (data) { document.getElementById("modes").innerHTML = ""; $.each(data,function (key,val) { var str = val.ModeKey + ': ' + val.ModeValue; $('<li/>',{ html: str }).appendTo($('#modes')); }); } }).fail( function (xhr,textStatus,err) { alert('Error: ' + err); }); } function add() { $.ajax({ url: "api/Test/",type: "POST",dataType: "json",data: { "ModeKey": document.getElementById("txtKey").value,"ModeValue": document.getElementById("txtValue").value },success: function (data) { getAll(); } }).fail( function (xhr,err) { alert('Error: ' + err); }); } function find() { $.ajax({ url: "api/Test/" + document.getElementById("txtFindKey").value,err) { alert('Error: ' + err); }); } function removeAll() { $.ajax({ url: "api/Test/",type: 'DELETE',success: function (data) { document.getElementById("modes").innerHTML = ""; getAll(); } }).fail( function (xhr,err) { alert('Error: ' + err); }); } function remove() { $.ajax({ url: "api/Test/"+document.getElementById("txtRemoveKey").value,err) { alert('Error: ' + err); }); } function update() { $.ajax({ url: "api/Test/",type: 'PUT',data: { "key": document.getElementById("txtUpdateKey").value,"value": document.getElementById("txtUpdateValue").value },err) { alert('Error: ' + err); }); } 这样就实现了最基本的CRUD操作。 (六)路由规则扩展 和普通的MVC一样,MVC WebAPI支持自定义的路由规则,如:在上面的操作中,路由规则使用 "api/{controller}/{id}"
则限定了使用GET方式利用URL来传值时,controller后面的接收参数名为id,但是在Controller中,GetOne方法的接收参数名为key,是不会被匹配的,这是只需要新增一个新的路由规则,或修改原先的路由规则为: "api/{controller}/{key}"
当然,可以对路由进行更深的扩展,如:扩展成和普通MVC一样的路由: "api/{controller}/{action}/{id}"
这样,就要求同时使用Action和HTTP方法进行匹配
(七)使用Attribute声明HTTP方法 有没有感觉默认的使用方法名来匹配HTTP Method的做法很傻??或者我有一些方法是自己用的,不想暴露出来,又该怎么办?还是使用attribute做这些工作感觉优雅一些,比如,上面的Action我可以更改为: [HttpGet] public IEnumerable<TestUseMode> FindAll() [HttpGet] public IEnumerable<TestUseMode> FindByKey(string key) [HttpPost] public bool Add(TestUseMode mode) [HttpDelete] public int RemoveByKey(string key) [HttpDelete] public int RemoveAll() [HttpPut] public int UpdateByKey(string key,string value) [NonAction] public string GetPrivateData() 当然,我只列出了方法名,而不是这些方法真的没有方法体...方法体是不变的,NoAction表示这个方法是不接收请求的,即使以GET开头。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |