MVC4 WEBAPI(一)使用概述
所谓概述,也就是总结一些WEB API常用的使用用法。MVC APIWEB是一个轻量级的服务接口,完全符合RestFul框架设计,每个URL代表一种资源,使用方便,没有WCF那么庞大,但是麻雀虽小五脏俱全,WEBAPI提供的内容很值得研究;API请求方式有GET、POST、PUT、DELETE。所以WEBAPI对应的APIControl提供的接口也分为以上4个类型。
1、WEBAPI创建:
使用的时候也很简单,利用VS2013新建项目,选择MVC4,让后选择WEBAPI,创建完成,这就是默认的MVC WEBAPI项目;
2、WEBAPI分析:
WEB API默认的路由是:
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
这个是默认提供的路由,通过路由,我们不难发现通过Control下的id进行匹配查找,所以接下的代码也是根据ID进行处理;由于服务请求的方式GET、POST、DELETE、PUT,所以每个APIControl也就提供这4中类型,针对这个轻量级框架,这4中方式处理好,一个APIControl应对自己的逻辑也就足够了。
代码展示:
public class ProductController : ApiController { static List<Product> products =new List<Product> () { new Product{Id=1,Name="Nokia Lumia 1520",Category="移动电话",Price=3500}, new Product{Id=2,Name="Lenovo Thinkpad T430S",Category="便携式计算机",Price=8000}, new Product{Id=3,Name="锤子手机",Category="移动电话",Price=3300}, new Product{Id=4,Name="Wii",Category="电视游戏机",Price=1000}, new Product{Id=5,Name="Xbox 360",Category="电视游戏机",Price=3200} }; /// <summary> /// Get /// </summary> /// <returns></returns> public IEnumerable<Product> GetAllProducts() { return products.OrderBy(p => p.Id); } /// <summary> /// Get /// </summary> /// <param name="id"></param> /// <returns></returns> public Product GetProductById(int id) { Product product = products.FirstOrDefault(p => p.Id == id); if (product==null) { var resp = new HttpResponseMessage(HttpStatusCode.NotFound); throw new HttpResponseException(resp); } return product; } /// <summary> /// Get /// </summary> /// <param name="productName"></param> /// <returns></returns> public Product GetProductByName(string productName,string category) { Product product = products.FirstOrDefault(p => p.Name.Contains(productName) && p.Category == category); if (product == null) { var resp = new HttpResponseMessage(HttpStatusCode.NotFound); throw new HttpResponseException(resp); } return product; } public IEnumerable<Product> GetAllProductsByCategory(string category) { if (category.Equals("--请选择--")) { return products; } IEnumerable<Product> productList = products.Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase)); return productList.OrderBy(p => p.Id); } public bool PostProduct(Product product) { int index = products.FindIndex(p => p.Name == product.Name); if (index != -1) { return false; } product.Id = products.Max(p => p.Id) + 1; products.Add(product); return true; } //public IEnumerable<Product> PostProductByCategory(string Category) //{ // //if (currpate.Category.Equals("--请选择--")) // //{ // // return products; // //} // //IEnumerable<Product> productList = products.Where(p => string.Equals(p.Category, currpate.Category, StringComparison.OrdinalIgnoreCase)); // return products;// productList.OrderBy(p => p.Id); //} //public IEnumerable<Product> PostProductByCategory22([FromBody] JObject currpate) //{ // dynamic json = currpate; // JObject curtxt = json.prodcut; // //if (currpate.Category.Equals("--请选择--")) // //{ // // return products; // //} // //IEnumerable<Product> productList = products.Where(p => string.Equals(p.Category, currpate.Category, StringComparison.OrdinalIgnoreCase)); // return products;// productList.OrderBy(p => p.Id); //} public bool PutProduct(int id, [FromBody]Product product) { int index = products.FindIndex(p => p.Id == id); if (index == -1) { return false; } products.RemoveAt(index); products.Add(product); return true; } /// <summary> /// DELETE /// </summary> /// <param name="id"></param> /// <returns></returns> public bool DeleteProduct(int id) { Product product = products.FirstOrDefault(p => p.Id == id); if (product == null) { return false; } else { products.Remove(product); return true; } } } }
代码分析:
以上就是一个简单的ControlAPI,通过代码分析,一个APIControl也就包含4中请求方式,准对GET方式请求,我们就要仔细区分ID参数进行逻辑判断。
看看客户端JS请求的方式:
<script type="text/javascript"> $(function () { $InitData(); $bindClick(); }); $InitData = function () { $.getJSON("../api/Product", function (data) { if (data != null) { if ($("#resultList").length > 0) { $("#resultList").remove(); } var html = "<ol id='resultList' class='round'>"; $.each(data, function (key, value) { html += "<li class='one'><h5>" + value.Name + "</h5>类型:" + value.Category + " 价格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>编辑</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>删除</a></li>"; }); html += "</ol>"; $("#result").append(html); } }); } $bindClick = function () { // 01.按产品类型搜索产品 $("#productTypes").bind("change", function () { //$.getJSON("../api/Product", { category: $(this).find("option:selected").text() }, function (data) { // if (data != null) { // $("#resultList").remove(); // var html = "<ol id='resultList' class='round'>"; // $.each(data, function (key, value) { // html += "<li class='one'><h5>" + value.Name + "</h5>类型:" + value.Category // + " 价格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>编辑</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>删除</a></li>"; // }); // html += "</ol>"; // $("#result").append(html); // } //}); var prodcut = { Category: "移动电话", Price:253, Id:5 }; var prodcut2 = { Category: "移动电话2", Price: 253, Id: 5 }; //$.ajax({ // type: "POST", // url: "../api/Product/PostProductByCategory", // data: JSON.stringify({ prot: prodcut }), // contentType: "application/json", // dataType:"xml", // success: function (data) { // console.log(data); // if (data != null) { // $("#resultList").remove(); // var html = "<ol id='resultList' class='round'>"; // $.each(data, function (key, value) { // html += "<li class='one'><h5>" + value.Name + "</h5>类型:" + value.Category // + " 价格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>编辑</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>删除</a></li>"; // }); // html += "</ol>"; // $("#result").append(html); // } // } //}); $.ajax({ type: "POST", url: "../api/Product", data: { Category: $("#editProductType").find("option:selected").text()}, success: function (data) { console.log(data); if (data != null) { $("#resultList").remove(); var html = "<ol id='resultList' class='round'>"; $.each(data, function (key, value) { html += "<li class='one'><h5>" + value.Name + "</h5>类型:" + value.Category + " 价格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>编辑</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>删除</a></li>"; }); html += "</ol>"; $("#result").append(html); } } }); }); // 02.按产品名搜索产品 $("#btnSearchByName").bind("click", function () { var searchName = $("#productName").val(); if (searchName == "") { showMsg("提示", "您还没有输入要搜索的产品名称"); } $.getJSON("../api/Product", { productName: searchName, category: '电视游戏机' }, function (data) { if (data != null) { $("#resultList").remove(); var html = "<ol id='resultList' class='round'>"; html += "<li class='one'><h5>" + data.Name + "</h5>类型:" + data.Category + " 价格:" + data.Price + " | <a href='#' onclick='editProduct(" + data.Id + ")'>编辑</a><a href='#' onclick='deleteProduct(" + data.Id + ")'>删除</a></li>"; html += "</ol>"; $("#result").append(html); clearText(); } }); }); // 03.搜索全部产品信息 $("#btnSearchAll").bind("click", $InitData); // 04.新增一个产品信息 $("#btnPostProduct").bind("click", function () { var productName = $("#newProductName").val(); var productCategory = $("#newProductType").find("option:selected").text(); var productPrice = $("#newProductPrice").val(); if (productName == "") { showMsg("提示", "请输入产品名称"); } else if (productCategory == "" || productCategory == "--请选择--") { showMsg("提示", "请选择产品类型"); } else if (productPrice == "") { showMsg("提示", "请输入产品价格"); } else if (isNaN(productPrice)) { showMsg("提示", "产品价格请输入数字类型"); } else { $.post("../api/Product", { Name: productName, Category: productCategory, Price: productPrice }, function (data) { if (data != null && data == true) { $InitData(); clearText(); showMsg("提示", "添加新产品操作成功"); } else { showMsg("提示", "添加新产品操作失败"); } }); } }); // 07.修改一个产品信息 $("#btnPutProduct").bind("click", function () { var productId = $("#hiddProductId").val(); $.ajax({ type: "PUT", url: "../api/Product/" + productId, data: { Id: productId, Name: $("#editProductName").val(), Category: $("#editProductType").find("option:selected").text(), Price: $("#editProductPrice").val() }, success: function (data) { if (data == true) { $InitData(); $("#myEditModal").window("close"); showMsg("提示", "您已成功修改那玩意"); } else { showMsg("提示", "修改那玩意操作失败"); } } }); }); // 关闭模态对话框 $("#btnCloseModal").bind("click", function () { $("#myEditModal").window("close"); }); } // 05.编辑一个产品信息 function editProduct(productId) { $.getJSON("../api/Product", { id: productId }, function (data) { if (data != null) { $("#hiddProductId").val(data.Id); $("#editProductName").val(data.Name); switch (data.Category) { case "移动电话": $("#editProductType").val("0"); break; case "便携式计算机": $("#editProductType").val("1"); break; case "电视游戏机": $("#editProductType").val("2"); break; } $("#editProductPrice").val(data.Price); } }); $("#myEditModal").show(); $("#myEditModal").window({ title: "编辑产品信息", modal: true, collapsible: true, minimizable: false, maximizable: false, resizable: false, width: 500, height: 220 }); } // 06.删除一个产品信息 function deleteProduct(productId) { $.messager.confirm("提示", "您确定要删除这玩意?", function (r) { if (r) { $.ajax({ type: "DELETE", url: "../api/Product/" + productId, data: {}, success: function (data) { if (data == true) { $InitData(); showMsg("提示", "您已成功删除那玩意"); } else { showMsg("提示", "删除那玩意操作失败"); } } }); } }); } function showMsg(title, msg) { $.messager.alert(title, msg, "info"); } function clearText() { $("input[type=text]").val(""); } </script>
JS也就是采用数据请求的方式,Ajax请求完成数据操作。
3、WEB API路由扩展:
在MVC中,大家看到的更多的路由模式是含有Action,可是WEBAPI就没有了,当然如果想使用自定义路由模式展现Action也是可行的,注册自定义路由
public static void Register(HttpConfiguration config) { //自定义路由 config.Routes.MapHttpRoute( name: "DefaultSprtApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); 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(); }
这这个里面,我们就把Action 加载里面了,有了这个Action,那么我们的APIControl又该怎么操作,才能获取我们想要的数据。不着急,这就展示APIControl代码
public IEnumerable<Product> PostProductByCategory22([FromBody] JObject currpate) { dynamic json = currpate; JObject curtxt = json.prodcut; //if (currpate.Category.Equals("--请选择--")) //{ // return products; //} //IEnumerable<Product> productList = products.Where(p => string.Equals(p.Category, currpate.Category, StringComparison.OrdinalIgnoreCase)); return products;// productList.OrderBy(p => p.Id); }
代码参数中多了一个FromBody,FromBody有什么功能那?查询CSDN发现,FromBody能够强制APIControl通过客户端或者Body读取参数,所以看看JS代码:
var prodcut = { Category: "移动电话", Price:253, Id:5 }; var prodcut2 = { Category: "移动电话2", Price: 253, Id: 5 }; $.ajax({ type: "POST", url: "../api/Product/PostProductByCategory", data: JSON.stringify({ prot: prodcut }), contentType: "application/json", dataType:"xml", success: function (data) { console.log(data); if (data != null) { $("#resultList").remove(); var html = "<ol id='resultList' class='round'>"; $.each(data, function (key, value) { html += "<li class='one'><h5>" + value.Name + "</h5>类型:" + value.Category + " 价格:" + value.Price + " | <a href='#' onclick='editProduct(" + value.Id + ")'>编辑</a><a href='#' onclick='deleteProduct(" + value.Id + ")'>删除</a></li>"; }); html += "</ol>"; $("#result").append(html); } } });
使用这个地方这种方式,客户端需要注意事项:
1、需要设置请求content-Type。这里设置为contentType: "application/json";
2、发送的数据格式JSon.
服务端ControlAPI也需要注意,这个只能设置一个类型为FromBody参数,所以逻辑一定要封装好。
参考文章:
http://blog.jobbole.com/85008/
http://www.cnblogs.com/wk1234/archive/2012/04/28/2468491.html
MVC:
http://www.cnblogs.com/babycool/p/3922738.html