WEBAPI
1.WEBAPI
在新出的MVC4中,增加了WebAPI,用于提供REST风格的WebService,新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models、Views、Controllers等文件夹和Global.asax文件。Views对于WebAPI来说没有太大的用途,Models中的Model主要用于保存Service和Client交互的对象,这些对象默认情况下会被转换为Json格式的数据迚行传输,Controllers中的Controller对应于WebService来说是一个Resource,用于提供服务。和普通的MVC一样,Global.asax用于配置路由规则。
REST风格:https://www.jianshu.com/p/6e8381c9b01d
2.示例
注意:再次强调Views对于WebAPI来说没有太大的用途,Models中的Model主要用于保存Service和Client交互的对象,这些对象默认情况下会被转换为Json格式的数据进行传输,Controllers中的Controller对应于WebService来说是一个Resource,用于提供服务。和普通的MVC一样,Global.asax用于配置路由规则
Model
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebAPI.Models { public class UserModel { public int Id { get; set; } public string UserName { get; set; } public string PassWord { get; set; } } }
Controller
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using WebAPI.Models; namespace WebAPI.Controllers { public class UserController : ApiController { public static 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,UserName="wang", PassWord="1234567"} }; //Get api/User [HttpGet] public IEnumerable<UserModel> Get() { return allModeList; } //Get api/User/1 [HttpGet] public IEnumerable<UserModel> GetOne(int id) { return allModeList.FindAll((x) => { return x.Id == id; }); } //Get api/User/?username=xxx [HttpGet] public IEnumerable<UserModel> GetOneByModel(string username) { return allModeList.FindAll((m) => { return m.UserName.Equals(username); }); } //Get api/User/?username=xxx&password=xxx public IEnumerable<UserModel> GetOneByModel(string username, string password) { return allModeList.FindAll((m => { return m.UserName.Equals(username) && m.PassWord.Equals(password); })); } //Post api/User [HttpPost] public bool PostNew(UserModel user) { try { allModeList.Add(user); return true; } catch (Exception ex) { return false; } } //DELETE api/User/1 [HttpDelete] public int DeleteOne(int id) { return allModeList.RemoveAll((x) => { return x.Id == id; }); } //DELETE api/User [HttpDelete] public int DeleteAll() { return allModeList.RemoveAll((x) => { return true; }); } //Put api/Put [HttpPut] public int PutOne(int id, UserModel user) { List<UserModel> list = allModeList. FindAll((mode) => { return mode.Id == id; }); foreach (var mode in list) { mode.PassWord = user.PassWord; mode.UserName = user.UserName; } return list.Count; } } }
Global
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace WebAPI { public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // 取消注释下面的代码行可对具有 IQueryable 或 IQueryable<T> 返回类型的操作启用查询支持。 // 若要避免处理意外查询或恶意查询,请使用 QueryableAttribute 上的验证设置来验证传入查询。 // 有关详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=279712。 //config.EnableQuerySupport(); // 若要在应用程序中禁用跟踪,请注释掉或删除以下代码行 // 有关详细信息,请参阅: http://www.asp.net/web-api config.EnableSystemDiagnosticsTracing(); } } }
URL,HTTPMETHOD,ACTION对应的关系
URL HttpMethod 对应的Action名
/api/User GET GetALL
/api/User/1 GET GetOne
/api/User POST PostNew
/api/User/1 DELETE DeleteOne
/api/User DELETE DeleteALL
/api/User PUT PutOne
JS客户端
<button onclick="getAll()">getAll</button> <button onclick="find()">find</button> <button onclick="add()">add</button> <button onclick="removeUser()">remove</button> <button onclick="removeAll()">removeAll</button> <button onclick="udpate()">udpate</button> <button onclick="getUserByName()">getUserByName</button> <button onclick="getUserByName2()">getUserByName2</button> <div id="body"></div> <div id="modes"></div> <script type="text/javascript"> function getAll() { $.ajax({ url: "api/User/", type: '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) { alert('Error: ' + err); }); } function find() { $.ajax({ //url: "api/User/?key=1" , url: "api/User/1", type: '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) { 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 (xhr, 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: ' + 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({ 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 (xhr, textStatus, err) { alert('Error: ' + err); }); } function getUserByName() { $.ajax({ url: "api/User/?userName=zhang", type: 'GET', success: function (data) { document.getElementById("modes").innerHTML = ""; var str = data.UserName + ': ' + data.PassWord; $('<li/>', { html: str }).appendTo($('#modes')); } }).fail( function (xhr, textStatus, err) { alert('Error: ' + err); }); } function getUserByName2() { $.ajax({ url: "api/User/?userName=zhang&passWord=123", type: 'GET', success: function (data) { document.getElementById("modes").innerHTML = ""; var str = data.UserName + ': ' + data.PassWord; $('<li/>', { html: str }).appendTo($('#modes')); } }).fail( function (xhr, textStatus, err) { alert('Error: ' + err); }); } </script>
以上实现了最基本的CRUD操作。
3. WEBAPI传参数 url: "api/User/?userName=zhang"
//Get api/User/?username=xxx [HttpGet] public IEnumerable<UserModel> GetOneByModel(string username) { return allModeList.FindAll((m) => { return m.UserName.Equals(username); }); } //Get api/User/?username=xxx&password=xxx public IEnumerable<UserModel> GetOneByModel(string username, string password) { return allModeList.FindAll((m => { return m.UserName.Equals(username) && m.PassWord.Equals(password); })); }
function getUserByName() { $.ajax({ url: "api/User/?userName=zhang", type: 'GET', success: function (data) { document.getElementById("modes").innerHTML = ""; var str = data.UserName + ': ' + data.PassWord; $('<li/>', { html: str }).appendTo($('#modes')); } }).fail( function (xhr, textStatus, err) { alert('Error: ' + err); }); } function getUserByName2() { $.ajax({ url: "api/User/?userName=zhang&passWord=123", type: 'GET', success: function (data) { document.getElementById("modes").innerHTML = ""; var str = data.UserName + ': ' + data.PassWord; $('<li/>', { html: str }).appendTo($('#modes')); } }).fail( function (xhr, textStatus, err) { alert('Error: ' + err); });
4. 路由规则扩展
和普通的MVC一样,MVC WebAPI支持自定义的路由规则,如:在上面的操作中,路由规则使用
"api/{controller}/{id}"
则限定了使用GET方式利用URL来传值时,controller后面的接收参数名为id,但是在Controller中,如果GetOne方法的接收参数名为key,是不会被匹配的,这是只需要新增一个新的路由规则,或修改原先的路由规则为:
"api/{controller}/{key}",如下所示:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{key}",
defaults: new { key = RouteParameter.Optional }
);
当然,可以对路由进行更深的扩展,如:扩展成和普通MVC一样的路由:
"api/{controller}/{action}/{id}"
这样,就要求同时使用Action和HTTP方法进行匹配。
5. 使用Attribute声明HTTP方法
[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开头。
如果感觉常规的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 true; return false; });
foreach(var mode in upDataList)
{
mode.ModeValue = value;
}
return upDataList.Count;
}
6. ASP.NET MVC4+WebAPI+FluentData
Model
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FluentData.Entity { public class Customer { public string CustomerID { get; 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; set; } public string Fax { get; set; } } }
Service
using FluentData.Entity; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FluentData.DAL { 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(); } 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>("*").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) currentPageIndex = 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(Customer customer) { int affected = context.Insert("Customers").Column("CustomerID", customer.CustomerID) .Column("CompanyName", customer.CompanyName) .Column("ContactName", customer.ContactName) .Column("Country", customer.Country) .Execute(); return affected; } public int Update(Customer customer) { int rowsAffected = context.Update("Customers").Column("CompanyName", customer.CompanyName) .Column("ContactName", customer.ContactName) .Column("Country", customer.Country) .Where("CustomerID", customer.CustomerID) .Execute(); return rowsAffected; } public int Delete(string customerId) { return context.Delete("Customers").Where("CustomerID", customerId).Execute(); } public int Delete(Customer customer) { return this.Delete(customer.CustomerID); } } }
Controller
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using FluentData.DAL; using FluentData.Entity; namespace WebAPI.Controllers { public class CustomerController : ApiController { private 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(customer); } //Update public void Put(string id, Customer obj) { customerService.Update(obj); } //Delete public void Delete(string id) { customerService.Delete(id); } } }
VIew
@{ ViewBag.Title = "CustomerManager"; } <h2>CustomerManager</h2> <table id="customerTable" border="1" cellpadding="3" style="width:700px"> <tr> <th>Customer ID</th> <th>Company Name</th> <th>Contact 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" 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><input type="button" name="btnInsert" value="Insert" style="width:150px" /></td> </tr> </table> <div id="#modes"></div> <script type="text/javascript"> $(function () { $.getJSON("api/Customer", LoadCustomers); }); function LoadCustomers(data) { $("#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 + '" /></td>' + '<td><input type="text" value="' + val.ContactName + '" /></td>' + '<td><input type="text" value="' + val.Country + '" /></td>' + '<td><input type="button" name="btnUpdate" value="修改" /> <input type="button" name="btnDelete" value="删除" /></td>' + '</tr>'; $('#customerTable').append(tableRow); }); $("input[name='btnInsert']").click(OnInsert); $("input[name='btnUpdate']").click(OnUpdate); $("input[name='btnDelete']").click(OnDelete); } function OnInsert(evt) { var customerId = $("#txtCustomerId").val(); var companyName = $("#txtCompanyName").val(); var contactName = $("#txtContactName").val(); var country = $("#txtCountry").val(); var data = '{"CustomerID":"' + customerId + '","CompanyName":"' + companyName + '","ContactName":"' + contactName + '","Country":"' + country + '"}'; $.ajax({ type: 'POST', url: '/api/Customer/', data: data, contentType: "application/json; charset=utf-8", dataType: 'json', success: function (results) { $("#txtCustomerId").val(''); $("#txtCompanyName").val(''); $("#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(); input = $($(this).parent().parent().children().get(2)).find("input"); //input.removeAttr("disabled"); var contactName = input.val(); input = $($(this).parent().parent().children().get(3)).find("input"); //input.removeAttr("disabled"); var country = input.val(); var data = '{"CustomerID":"' + customerId + '","CompanyName":"' + companyName + '","ContactName":"' + contactName + '","Country":"' + country + '"}'; $.ajax({ type: 'PUT', url: '/api/Customer/' + customerId, data: data, contentType: "application/json; charset=utf-8", dataType: 'json', success: function (results) { $.getJSON("api/Customer" + new Date().getTime(), LoadCustomers); alert('修改成功 !'); } }).fail( function (xhr, textStatus, err) { alert('修改失败,原因如下: ' + err); }); } function OnDelete(evt) { var customerId = $(this).parent().parent().children().get(0).innerHTML; //var data = '{"id":"' + customerId + '"}'; //var row = $(this).parent().parent(); $.ajax({ type: 'DELETE', url: '/api/Customer/' + customerId, contentType: "application/json; charset=utf-8", dataType: 'json', success: function (results) { $.getJSON("api/Customer?" + new Date().getTime(), LoadCustomers); alert('成功删除!'); } }).fail( function (xhr, textStatus, err) { alert('删除失败,原因如下: ' + err); }); } </script>
7.webapi 高级部分