《Asp.Net Web Api 》-----路由机制

来源:互联网 发布:软通动力java试题2016 编辑:程序博客网 时间:2024/05/17 03:37

    前言

   上一篇文章小编大体说了一下WebApi的简单应用程序,今天小编跟大家来讨论一下WebApi中的路由。如果你熟悉ASP.NET MVC,Web API路由与MVC路由十分类似。主要差别是Web API使用HTTP方法而不是URI路径来选择动作。你也可以在Web API中使用MVC风格的路由。

   1、路由表

   在ASP.NET Web API中,一个控制器是处理HTTP请求的一个类。控制器的public方法称为动作方法(action methods)或简称为动作(action)。当Web API框架接收到一个请求时,它将这个请求路由到一个动作。

   为了确定调用哪一个动作,框架使用了一个路由表(routing table)。Visual Studio中Web API的项目模板会创建一个默认路由,这条路由是在WebApiConfig.cs文件中定义的,该文件位于App_Start目录。

   

public static void Register(HttpConfiguration config)        {            config.Routes.MapHttpRoute(                name: "DefaultApi",                routeTemplate: "api/{controller}/{id}",                defaults: new { id = RouteParameter.Optional }            );            config.EnableSystemDiagnosticsTracing();        }

   路由表中的每一个条目都包含一个路由模板(route template)。Web API的默认路由模板是“api/{controller}/{id}”。在这个模板中,“api”是一个文字式路径片段,而{controller}和{id}则是占位符变量。

   当Web API框架接收一个HTTP请求时,它会试图根据路由表中的一个路由模板来匹配其URI。如果无路由匹配,客户端会接收到一个404(未找到)错误。例如,以下URI与这个默认路由的匹配:

  • /api/contacts
  • /api/contacts/1
  • /api/products/gizmo1

   在路由中使用“api”的原因是为了避免与ASP.NET MVC的路由冲突。通过这种方式,可以用“/contacts”进入一个MVC控制器,而“/api/contacts”进入一个Web API控制器。当然,如果你不喜欢这种约定,可以修改这个默认路由表。

   一旦找到了匹配路由,Web API便会选择相应的控制和动作:为了找到控制器,Web API会把“控制器”加到{controller}变量的值(意即,把URI中的“控制器”作为{controller}变量的值)。为了找到动作,Web API会考查HTTP方法,然后寻找一个名称以HTTP方法名开头的动作。例如,对于一个GET请求,Web API会查找一个以“Get…”开头的动作,如“GetProduct”或“GetAllProduct”等。这种约定仅运用于GET、POST、PUT和DELETE方法。通过把注解属性运用于控制器,你可以启用其它HTTP方法。后面会看到一个例子。路由模板中的其它占位变量,如{id},被映射成动作参数。

   2、Demo    

public class WebApiController : ApiController    {        /// <summary>        /// 定义一个产品数据        /// </summary>        Product[] products = new Product[]         {             new Product { Id = 1, Name = "农夫山泉", Category = "water", Price = 2 },             new Product { Id = 2, Name = "钢笔", Category = "study", Price = 3.75M },             new Product { Id = 3, Name = "烤肠", Category = "food", Price = 1 },            new Product { Id = 4, Name = "崂山矿泉水", Category = "water", Price = 2 },             new Product { Id = 5, Name = "铅笔", Category = "study", Price = 3.75M },             new Product { Id = 6, Name = "烤羊肉串", Category = "food", Price = 1 }         };        /// <summary>        /// 得到所有的产品        /// </summary>        /// <returns></returns>        public IEnumerable<Product> GetAllProducts()        {            return products;        }        /// <summary>        /// 根据id查询产品        /// </summary>        /// <param name="id">产品id</param>        /// <returns></returns>        public Product GetProductById(int id)        {            var product = products.FirstOrDefault((p) => p.Id == id);            if (product == null)            {                throw new HttpResponseException(HttpStatusCode.NotFound);            }            return product;        }        /// <summary>        /// 根据产品种类查询产品        /// </summary>        /// <param name="category">产品种类</param>        /// <returns></returns>        public IEnumerable<Product> GetProductsByCategory(string category)        {            return products.Where(                (p) => string.Equals(p.Category, category,                    StringComparison.OrdinalIgnoreCase));        }        /// <summary>        /// 根据id删除        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public List<int> DeleteProductById(int id)        {            List<int> p = new List<int>();            for (int i = 0; i < 6; i++)                p.Add(i);            p.Remove(id);            if (p == null)            {                throw new HttpResponseException(HttpStatusCode.NotFound);            }            return p;        }        /// <summary>        /// 根据id增加        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public List<int> PostProductById(int id)        {            List<int> p = new List<int>();            for (int i = 0; i < id; i++)                p.Add(i);            if (p == null)            {                throw new HttpResponseException(HttpStatusCode.NotFound);            }            return p;        }    }

  我们启动程序后,可以继续使用Postman测试这几个方法。  

   其它的几个测试方法我省略。现在我们更改一下路由表,使其根据Controller 来确定访问哪个类,根据Action来确定访问哪个方法。    

public static void Register(HttpConfiguration config)        {            config.Routes.MapHttpRoute(               name: "DefaultApi",               routeTemplate: "{controller}/{action}/{id}",               defaults: new { id = RouteParameter.Optional }           );            config.EnableSystemDiagnosticsTracing();        }

  对应的方法:  

public class RouteDemoController : ApiController    {        Product[] products = new Product[]         {             new Product { Id = 1, Name = "农夫山泉", Category = "water", Price = 2 },             new Product { Id = 2, Name = "钢笔", Category = "study", Price = 3.75M },             new Product { Id = 3, Name = "烤肠", Category = "food", Price = 1 },            new Product { Id = 4, Name = "崂山矿泉水", Category = "water", Price = 2 },             new Product { Id = 5, Name = "铅笔", Category = "study", Price = 3.75M },             new Product { Id = 6, Name = "烤羊肉串", Category = "food", Price = 1 }         };        /// <summary>        /// 查询所有商品        /// </summary>        /// <returns></returns>        [HttpGet]        public IEnumerable<Product> QueryAllProducts()        {            return products;        }        /// <summary>        /// 根据id查询商品        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        [HttpGet]        public Product QueryProductById(int id)        {            var product = products.FirstOrDefault((p) => p.Id == id);            if (product == null)            {                throw new HttpResponseException(HttpStatusCode.NotFound);            }            return product;        }        /// <summary>        /// 根据种类查询商品        /// </summary>        /// <param name="category"></param>        /// <returns></returns>        [HttpGet]        public IEnumerable<Product> QueryProductsByCategory(string category)        {            return products.Where(                (p) => string.Equals(p.Category, category,                    StringComparison.OrdinalIgnoreCase));        }        /// <summary>        /// 此动作不让请求        /// </summary>        [NonAction]         public void PrivateData()        {                 }           }

  测试效果如下 

    

    

  这就是更改过后的路由,有时候,我们还可以使用注解属性来代替Action的使用

[HttpGet]        [ActionName("Test")]         public Product findProductById(int id)        {            var product = products.FirstOrDefault((p) => p.Id == id);            if (product == null)            {                throw new HttpResponseException(HttpStatusCode.NotFound);            }            return product;        }

  测试结果如下

    

  3、小结

  这就是小编了解到的WebApi的路由,其实WebApi和Mvc方法中的区别是,MVC中返回的是视图的名字,而WebApi是返回的是数据。WebApi与WCF相比,WebApi比WCF重量级要小,小编所在的项目组用的就是WebApi,我们将css、HTML、AngularJS,打包成apk后,让用户按上,我们可以直接在apk中调用WebApi的服务。好了,小编总结到这吧。

2 0
原创粉丝点击