20、ASP.NET MVC入门到精通——WebAPI
本系列目录:ASP.NET MVC4入门到精通系列目录汇总
微软有了Webservice和WCF,为什么还要有WebAPI?
用过WCF的人应该都清楚,面对那一大堆复杂的配置文件,有时候一出问题,真的会叫人抓狂。而且供不同的客户端调用不是很方便。不得不承认WCF的功能确实非常强大,可是有时候我们通常不需要那么复杂的功能,只需要简单的仅通过使用Http或Https来调用的增删改查功能,这时,WebAPI应运而生。那么什么时候考虑使用WebAPI呢?
当你遇到以下这些情况的时候,就可以考虑使用Web API了。
- 需要Web Service但是不需要SOAP
- 需要在已有的WCF服务基础上建立non-soap-based http服务
- 只想发布一些简单的Http服务,不想使用相对复杂的WCF配置
- 发布的服务可能会被带宽受限的设备访问
- 希望使用开源框架,关键时候可以自己调试或者自定义一下框架
熟悉MVC的朋友你可能会觉得Web API 与MVC很类似。
Demo
1、新建项目,WebApi
2、新建类Product
public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } }
3、新建控制器Products,为了演示,我这里不连接数据库,直接代码中构造假数据
using System.Net.Http;
using System.Web.Http;
public class ProductsController : ApiController { Product[] products = new Product[] { new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } }; public IEnumerable<Product> GetAllProducts() { return products; } public IHttpActionResult GetProduct(int id) { var product = products.FirstOrDefault((p) => p.Id == id); if (product == null) { return NotFound(); } return Ok(product); } }
4、新建Index.html来测试WebAPI的调用,代码如下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Product App</title> </head> <body> <div> <h2>All Products</h2> <ul id="products" /> </div> <div> <h2>Search by ID</h2> <input type="text" id="prodId" size="5" /> <input type="button" value="Search" onclick="find();" /> <p id="product" /> </div> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script> <script> var uri = 'api/products'; $(document).ready(function () { $.getJSON(uri) .done(function (data) { $.each(data, function (key, item) { $('<li>', { text: formatItem(item) }).appendTo($('#products')); }); }); }); function formatItem(item) { return item.Name + ': $' + item.Price; } function find() { var id = $('#prodId').val(); $.getJSON(uri + '/' + id) .done(function (data) { $('#product').text(formatItem(data)); }) .fail(function (jqXHR, textStatus, err) { $('#product').text('Error: ' + err); }); } </script> </body> </html>
运行结果如下:
WebAPI授权
1、新建授权过滤器类APIAuthorizeAttribute.cs
/* ============================================================================== * 功能描述:APIAuthorizeAttribute * 创 建 者:Zouqj * 创建日期:2015/11/3 11:37:45 ==============================================================================*/ using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Principal; using System.Text; using System.Threading; using System.Web; using System.Web.Http.Filters; using Uuch.HP.WebAPI.Helper; namespace Uuch.HP.WebAPI.Filter { public class APIAuthorizeAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) { //如果用户使用了forms authentication,就不必在做basic authentication了 if (Thread.CurrentPrincipal.Identity.IsAuthenticated) { return; } var authHeader = actionContext.Request.Headers.Authorization; if (authHeader != null) { if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) && !String.IsNullOrWhiteSpace(authHeader.Parameter)) { var credArray = GetCredentials(authHeader); var userName = credArray[0]; var key = credArray[1]; string ip = System.Web.HttpContext.Current.Request.UserHostAddress; //if (IsResourceOwner(userName, actionContext)) //{ //You can use Websecurity or asp.net memebrship provider to login, for //for he sake of keeping example simple, we used out own login functionality if (APIAuthorizeInfoValidate.ValidateApi(userName,key,ip))//Uuch.HPKjy.Core.Customs.APIAuthorizeInfo.GetModel(userName, key, ip) != null { var currentPrincipal = new GenericPrincipal(new GenericIdentity(userName), null); Thread.CurrentPrincipal = currentPrincipal; return; } //} } } HandleUnauthorizedRequest(actionContext); } private string[] GetCredentials(System.Net.Http.Headers.AuthenticationHeaderValue authHeader) { //Base 64 encoded string var rawCred = authHeader.Parameter; var encoding = Encoding.GetEncoding("iso-8859-1"); var cred = encoding.GetString(Convert.FromBase64String(rawCred)); var credArray = cred.Split(':'); return credArray; } private bool IsResourceOwner(string userName, System.Web.Http.Controllers.HttpActionContext actionContext) { var routeData = actionContext.Request.GetRouteData(); var resourceUserName = routeData.Values["userName"] as string; if (resourceUserName == userName) { return true; } return false; } private void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); actionContext.Response.Headers.Add("WWW-Authenticate", "Basic Scheme='eLearning' location='http://localhost:8323/APITest'"); } } }