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

    前言

   上一篇文章小编大体说了一下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的服务。好了,小编总结到这吧。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值