WebAPI 从入门到精通_第1页
WebAPI 从入门到精通_第2页
WebAPI 从入门到精通_第3页
WebAPI 从入门到精通_第4页
WebAPI 从入门到精通_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第1章 .实例快速上手 -ASP.NET 4.5新特性WebAPI从入门到精通 在新出的MVC4中,增加了WebAPI,用于提供REST风格的WebService,新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models、Views、Controllers等文件夹和Global.asax文件。Views对于WebAPI来说没有太大的用途,Models中的Model主要用于保存Service和Client交互的对象,这些对象默认情况下会被转换为Json格式的数据迚行传输,Controllers中的Controller对应于WebService来说是一个Resource,用于提供服务

2、。和普通的MVC一样,Global.asax用于配置路由规则。(1) 环境准备 建议使用VS2012以上版本创建WebAPI,如果是使用VS2010,需要安装VS2010 SP1升级包,MVC4升级包,打开VS2012创建如下:第一步:新建ASP.NET Web应用程序第二步:建议WebAPI新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models,Views,Controllers等文件夹和Global.asax文件注意:再次强调Views对于WebAPI来说没有太大的用途,Models中的Model主要用于保存Service和Client交互的对象,这些对象默认情况下会被转换

3、为Json格式的数据进行传输,Controllers中的Controller对应于WebService来说是一个Resource,用于提供服务。和普通的MVC一样,Global.asax用于配置路由规则(二)Models和WCF中的数据契约形成鲜明对比的是,MVC WebAPI中的Model就是简单的POCO,没有任何别的东西,如,你可以创建如下的Model public class UserModel public int Id get; set; public string UserName get; set; public string PassWord get; set; 注意:Mod

4、el必须提供public的属性,用于json或xml反序列化时的赋值(三)ControllersMVC WebAPI中的Controllers和普通MVC的Controllers类似,不过不再继承于Controller,而改为继承API的ApiController,一个Controller可以包含多个Action,这些Action响应请求的方法与Global中配置的路由规则有关,在后面结束Global时统一说明(四)Global默认情况下,模板自带了两个路由规则,分别对应于WebAPI和普通MVC的Web请求,默认的WebAPI路由规则如下1 routes.MapHttpRoute(2 nam

5、e: "DefaultApi",3 routeTemplate: "api/controller/id",4 defaults: new id = RouteParameter.Optional 5 );可以看到,默认路由使用的固定的api作为Uri的先导,按照微软官方的说法,用于区分普通Web请求和WebService的请求路径:可以看到,默认的路由规则只指向了Controller,没有指向具体的Action,因为默认情况下,对于Controller中的Action的匹配是和Action的方法名相关联的:具体来说,如果使用上面的路由规则,对应下面的Co

6、ntroller:public class UserController : ApiController public List<UserModel> allModeList = new List<UserModel>() new UserModel() Id=1,UserName="zhang", PassWord="123", new UserModel() Id=2,UserName="lishi", PassWord="123456", new UserModel() Id=3,Us

7、erName="wang", PassWord="1234567" ; /Get api/User/ public IEnumerable<UserModel> GetAll() return allModeList; /Get api/User/1 public IEnumerable<UserModel> GetOne(int id) return allModeList.FindAll(m) => return m.Id = id; ); /POST api/User/ public bool PostNew(User

8、Model user) try allModeList.Add(user); return true; catch return false; /Delete api/User/ public int DeleteAll() return allModeList.RemoveAll(mode) => return true; ); /Delete api/User/1 public int DeleteOne(int id) return allModeList.RemoveAll(m) => return m.Id = id; ); /Put api/User public in

9、t PutOne(int id, UserModel user) List<UserModel> upDataList = allModeList.FindAll(mode) => return mode.Id = id; ); foreach (var mode in upDataList) mode.PassWord = user.PassWord; mode.UserName = user.UserName; return upDataList.Count; 则,会有下面的对应关系: URL HttpMethod 对应的Action名 /api/User GET Get

10、ALL /api/User/1 GET GetOne /api/User POST PostNew /api/User/1 DELETE DeleteOne /api/User DELETE DeleteALL /api/User PUT PutOne(5) 客户端JS调用 function getAll() $.ajax( url: "api/User/", type: 'GET', success: function (data) document.getElementById("modes").innerHTML = "&

11、quot; $.each(data, function (key, val) var str = val.UserName + ': ' + val.PassWord; $('<li/>', html: str ).appendTo($('#modes'); ); ).fail( function (xhr, textStatus, err) alert('Error: ' + err); );function find() $.ajax( url: "api/User/1" , type: 

12、9;GET', success: function (data) document.getElementById("modes").innerHTML = "" $.each(data, function (key, val) var str = val.UserName + ': ' + val.PassWord; $('<li/>', html: str ).appendTo($('#modes'); ); ).fail( function (xhr, textStatus, err

13、) alert('Error: ' + err); ); function add() $.ajax( url: "api/User/", type: "POST", dataType: "json", data: "Id":4,"UserName": "admin", "PassWord": "666666", success: function (data) getAll(); ).fail( function (x

14、hr, textStatus, err) alert('Error: ' + err); ); function removeUser() $.ajax( url: "api/User/3", type: 'DELETE', success: function (data) document.getElementById("modes").innerHTML = "" getAll(); ).fail( function (xhr, textStatus, err) alert('Error:

15、' + err); ); function removeAll() $.ajax( url: "api/User/", type: 'DELETE', success: function (data) document.getElementById("modes").innerHTML = "" getAll(); ).fail( function (xhr, textStatus, err) alert('Error: ' + err); ); function udpate() $.ajax

16、( url: "api/User/1", type: 'PUT', dataType: "json", data: Id: 1, "UserName": "admin", "PassWord": "666666" , success: function (data) document.getElementById("modes").innerHTML = "" getAll(); ).fail( function (xh

17、r, textStatus, err) alert('Error: ' + err); ); 这样就实现了最基本的CRUD操作。扩展需求问题1:我想按照用户名称(UserName)进行查询,怎么办?办法:第一步:在UserController类中加一个方法名称叫:GetUserByName,如下所示: public UserModel GetUserByName(string userName) return allModeList.Find(m) => return m.UserName.Equals(userName); );第二步:在客户端index.cshtml中

18、调用 function getUserByName() $.ajax( url: "api/User/zhang", type: 'GET', success: function (data) document.getElementById("modes").innerHTML = "" var str = data.UserName + ': ' + data.PassWord; $('<li/>', html: str ).appendTo($('#modes&#

19、39;); ).fail( function (xhr, textStatus, err) alert('Error: ' + err); );如果URL是: url: "api/User/zhang",将会报错:Bad Request原因是他会自动调用我们的GetOne(int id) 这个方法,类型转换出错解决办法:改变URL为: url: "api/User/?userName=zhang",问题2:我想按用户名称(UserName) 和用户密码(PassWord)一起来进行查询,怎么办?解决办法第一步:UserController

20、类中,可以重载一个GetUserByName的方法,如下所示: public UserModel GetUserByName(string userName) return allModeList.Find(m) => return m.UserName.Equals(userName); ); 第二步:客户端调用: function getUserByName() $.ajax( url: "api/User/?userName=zhang&passWord=123", /这里尤其需要注意 type: 'GET', success: func

21、tion (data) document.getElementById("modes").innerHTML = "" var str = data.UserName + ': ' + data.PassWord; $('<li/>', html: str ).appendTo($('#modes'); ).fail( function (xhr, textStatus, err) alert('Error: ' + err); );(6) 路由规则扩展和普通的MVC一样,MVC

22、 WebAPI支持自定义的路由规则,如:在上面的操作中,路由规则使用"api/controller/id"则限定了使用GET方式利用URL来传值时,controller后面的接收参数名为id,但是在Controller中,如果GetOne方法的接收参数名为key,是不会被匹配的,这是只需要新增一个新的路由规则,或修改原先的路由规则为:"api/controller/key",如下所示: config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/co

23、ntroller/key", defaults: new key = RouteParameter.Optional );当然,可以对路由进行更深的扩展,如:扩展成和普通MVC一样的路由:"api/controller/action/id"这样,就要求同时使用Action和HTTP方法进行匹配当然,根据微软的说法,这种使用是不被推荐的,因为这不符合大家对WebService的一般认知:(7) 使用Attribute声明HTTP方法 HttpGet public IEnumerable<TestUseMode> FindAll() HttpGet pub

24、lic 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()当然,我只列出了方法名,而不是这些方法真的没有

25、方法体.方法体是不变的,NoAction表示这个方法是不接收请求的,即使以GET开头。如果感觉常规的GET,POST,DELETE,PUT不够用,还可以使用AcceptVerbs的方式来声明HTTP方法,如:AcceptVerbs("MKCOL", "HEAD")public int UpdateByKey(string key, string value) List<TestUseMode> upDataList = allModeList.FindAll(mode) => if (mode.ModeKey = key) return

26、 true; return false; ); foreach(var mode in upDataList) mode.ModeValue = value; return upDataList.Count;附:什么是REST风格? 参考:什么是REST风格第二部分:综合示例:应用ASP.NET MVC4+WebAPI+FluentData开发Web应用第一步:创建数据库NorthWind数据库的Customers表Create DataBase NorthWindGoUse NorthWindGoCREATE TABLE dbo.Customers(CustomerID nchar(5) N

27、OT NULL,CompanyName nvarchar(40) NOT NULL,ContactName nvarchar(30) NULL,ContactTitle nvarchar(30) NULL,Address nvarchar(60) NULL,City nvarchar(15) NULL,Region nvarchar(15) NULL,PostalCode nvarchar(10) NULL,Country nvarchar(15) NULL,Phone nvarchar(24) NULL,Fax nvarchar(24) NULL, CONSTRAINT PK_Custome

28、rs PRIMARY KEY CLUSTERED (CustomerID ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON PRIMARY) ON PRIMARYGO第二步:创建 FluentData.Entity层,创建Customer实体类namespace FluentData.Entity public class Customer public string CustomerID g

29、et; set; public string CompanyName get; set; public string ContactName get; set; public string ContactTitle get; set; public string Address get; set; public string City get; set; public string Region get; set; public string PostalCode get; set; public string Country get; set; public string Phone get

30、; set; public string Fax get; set; 第三步:利用FluentData做数据的持久化首先引入FluentData.cs (见附件)其次:创建DBHelper类,代码如下: public class DBHelper public static IDbContext Context() /return new DbContext().ConnectionString("server=;uid=sa;pwd=sa;database=TestDB", new SqlServerProvider(); return new DbCo

31、ntext().ConnectionStringName("connString", new SqlServerProvider(); 然后不要忘记修改ASP.NET MVC层所在的Web.config,加入数据库连结字符串: <connectionStrings> <add name="connString" connectionString="server=;database=Northwind;uid=sa;pwd=sa;"/> </connectionStrings>第三步

32、:创建 CustomerService数据持久化类,代码如下:public class CustomerService private IDbContext context = DBHelper.Context(); public Customer Select(string customerId) return context.Select<Customer>("*").From("Customers").Where("CustomerID=0").Parameters(customerId) .QuerySingle(

33、); public List<Customer> SelectAll() return context.Select<Customer>("*").From("Customers").QueryMany(); public List<Customer> SelectAll(string sortExpression) if (String.IsNullOrEmpty(sortExpression) return null; return context.Select<Customer>("*&qu

34、ot;).From("Customers").OrderBy(sortExpression).QueryMany(); public List<Customer> SelectAll(int currentPageIndex,int maxRows, string sortExpression) var select = context.Select<Customer>("*").From("Customers"); if (maxRows > 0) if (currentPageIndex = 0) c

35、urrentPageIndex = 1; select.Paging(currentPageIndex, maxRows); if (!string.IsNullOrEmpty(sortExpression) select.OrderBy(sortExpression); return select.QueryMany(); public int CountAll() return context.Sql("select count(*) from Customers").QuerySingle<int>(); public int Insert(Custome

36、r customer) return context.Insert<Customer>("Customers", customer).Execute(); public int Update(Customer customer) return context.Update<Customer>("Customers", customer).Where("CustomerID", customer.CustomerID).Execute(); public int Delete(string customerId)

37、 return context.Delete("Customers").Where("CustomerID", customerId).Execute(); public int Delete(Customer customer) return this.Delete(customer.CustomerID); 第四步:Web API,创建CustomerController注意要引用:FluentData.Entity及FluentData.DAL 程序集public class CustomerController : ApiController p

38、rivate CustomerService customerService = new CustomerService(); /Select All public IEnumerable<Customer> Get() return customerService.SelectAll(); /Select By Id public Customer Get(string id) return customerService.Select(id); /Insert public void Post(Customer customer) customerService.Insert(

39、customer); /Update public void Put(string id, Customer obj) customerService.Update(obj); /Delete public void Delete(string id) customerService.Delete(id); 第五步:View层代码namespace MyWebApI.Controllers public class HomeController : Controller public ActionResult Index() return View(); public ActionResult

40、 Test() return View(); public ActionResult CustomerManager() return View(); 然后创建View <table id="customerTable" border="1" cellpadding="3" style="width:700px"> <tr> <th>Customer ID</th> <th>Company Name</th> <th>Contact

41、 Name</th> <th>Country</th> <th>Actions</th> </tr> <tr> <td><input type="text" id="txtCustomerId" style="width:100px" size="5"/></td> <td><input type="text" id="txtCompanyName&

42、quot; style="width:150px" /></td> <td><input type="text" id="txtContactName" style="width:150px"/></td> <td><input type="text" id="txtCountry" style="width:150px"/></td> <td><i

43、nput type="button" name="btnInsert" value="Insert" style="width:150px"/></td> </tr> </table><script type="text/javascript"> $(function () $.getJSON("api/Customer", LoadCustomers); ); function LoadCustomers(data) $

44、("#customerTable").find("tr:gt(1)").remove(); $.each(data, function (key, val) var tableRow = '<tr>' + '<td>' + val.CustomerID + '</td>' + '<td><input type="text" value="' + val.CompanyName + '" /&

45、gt;</td>' + '<td><input type="text" value="' + val.ContactName + '" /></td>' + '<td><input type="text" value="' + val.Country + '" /></td>' + '<td><input type="butt

46、on" name="btnUpdate" value="修改" /> <input type="button" name="btnDelete" value="删除" /></td>' + '</tr>' $('#customerTable').append(tableRow); ); $("inputname='btnInsert'").click(OnInsert)

47、; $("inputname='btnUpdate'").click(OnUpdate); $("inputname='btnDelete'").click(OnDelete); function OnInsert(evt) var customerId = $("#txtCustomerId").val(); var companyName = $("#txtCompanyName").val(); var contactName = $("#txtContactName

48、").val(); var country = $("#txtCountry").val(); var data = '"CustomerID":"' + customerId + '","CompanyName":"' + companyName + '","ContactName":"' + contactName + '","Country":"'

49、 + country + '"' $.ajax( type: 'POST', url: '/api/Customer/', data: data, contentType: "application/json; charset=utf-8", dataType: 'json', success: function (results) $("#txtCustomerId").val(''); $("#txtCompanyName").val(

50、9;'); $("#txtContactName").val(''); $("#txtCountry").val(''); $.getJSON("api/customers" + new Date().getTime(), LoadCustomers); alert('添加成功!'); ).fail( function (xhr, textStatus, err) alert('添加失败,原因如下: ' + err); ); function OnUpdate(evt) var input; var customerId = $(this).parent().parent().children().get(0).innerHTML; input = $($(this).parent().parent().children().get(1).find("input"); /input.removeAttr("disabled"); var companyName = input.val

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论