MVC——WebApi(学习之路1)

首先是在网址https://www.cnblogs.com/landeanfen/p/5501490.html博客学习。

一、MVC和WebApi路由机制比较

1、MVC里面的路由

在MVC里面,默认路由机制是通过url路径去匹配对应的action方法,比如/Home/GetUser这个url,就表示匹配Home这个Controller下面的GetUser方法,这个很好理解,因为在MVC里面定义了一个默认路由,在App_Start文件夹下面有一个RouteConfig.cs文件

复制代码

    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Department", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

复制代码

url: "{controller}/{action}/{id}"这个定义了我们url的规则,{controller}/{action}定义了路由的必须参数,{id}是可选参数

二、WebApi路由基础

1、默认路由

上面我们提到了,新建一个WebApi服务的时候,会自动在WebApiConfig.cs文件里面生成一个默认路由:

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

将MapHttpRoute()方法转到定义可以,它有四个重载方法:

分别来看看各个参数的作用:

  • name:"DefaultApi"→表示此路由的名称,这里只需要保证路由名称不重复就OK了。
  • routeTemplate: "api/{controller}/{id}"→表示路由的url规则,“api”是固定部分,主要用来标识当前请求的url是一个api服务的接口,区别MVC的路由,当然,这里并不是一定要写成“api”,如果你改成“apiserver”,那么你请求的url里面也需要写成“apiserver”;“{controller}”是控制器的占位符部分,在真实的url里面,该部分对应的是具体的控制器的名称,这个和MVC里面一致;“{id}”是参数的占位符部分,表示参数,一般这个参数都会在default里面设置可选。有了这个路由模板约束请求的url,比如:我们请求的url写成http://localhost:21528/Order,那么肯定是找不到对应的路由的,因为“api”这个参数必选。如果请求的url匹配不到对应的路由,则会向客户端返回一个404的状态码。
  • defaults: new { id = RouteParameter.Optional }→表示路由的默认值,比如上面的routeTemplate,{controller}和{id}部分都可以设置默认值,比如:defaults改成new { controller="Order", id = RouteParameter.Optional },那么我们请求http://localhost:21528/api这个url仍然能访问到GetAll()方法。
  • constraints→表示路由约束,一般是一个约束路由模板的正则表达式。比如:我们加入约束条件 constraints: new { id = @"\d+" } ,这就约束必须要匹配一到多个参数id,那么,我们在OrderController里面加入另一个方法

复制代码

    public class OrderController : ApiController
    {

        [HttpGet]
        public object GetAll()
        {
            return "Success";
        }

        [HttpGet]
        public object GetById(int id)
        {
            return "Success" + id ;
        }
    }

复制代码

我们通过http://localhost:21528/api/Order/2来访问,得到结果:

我们再通过http://localhost:21528/api/Order/a来访问,得到结果:

这个是很好理解的,id的值不匹配正则表达式。

而我们访问http://localhost:21528/api/Order。结果:

竟然连GetAll()方法都找不到了。这是为什么呢?原来就是这个约束在作怪,正则\d+表示匹配一个或多个数字,所以如果请求的url里面没有传数字,则自动匹配不到。所以,如果需要匹配无参的方法,我们把约束改成这样: constraints: new { id = @"\d*" } ,这个表示匹配0个或多个数字,再来试试

这样就OK了。

上述说了那么多都是约束id的,其实你也可以使用表达式去约束controller、action等等,但一般不常用,我们就不做过多讲解。

回到顶部

2、自定义路由

上面介绍了这么多,都是关于默认路由原理的介绍。除了默认路由,我们也可以自定义路由,我们将WebApiConfig.cs里面改成这样:

复制代码

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 路由
            config.MapHttpAttributeRoutes();

            //1.默认路由
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //2.自定义路由一:匹配到action
            config.Routes.MapHttpRoute(
                name: "ActionApi",
                routeTemplate: "actionapi/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //3.自定义路由二
            config.Routes.MapHttpRoute(
                name: "TestApi",
                routeTemplate: "testapi/{controller}/{ordertype}/{id}",
                defaults: new { ordertype="aa", id = RouteParameter.Optional }
            );
        }
    }

复制代码

除了默认路由,我们再加入另外两个自定义路由规则

2.1、自定义路由一:匹配到action

第一个自定义路由很好理解,和MVC里面的路由机制保持一致,只不过为了区别默认路由,我们将路由模板的前缀改成了“actionapi”。我们通过这个自定义的路由也能找到匹配的方法。

比如我们访问http://localhost:21528/actionapi/Order/GetAll,得到结果:

通过action的名称来匹配很好理解,上面的GetAll()是方法名,webApi会默认它就是action的名称,如果你想要方法名和action的名称不一致,你也可以自定义action的名称,这个可以通过特性ActionName来实现,如下:

        [ActionName("TestActionName")]
        [HttpGet]
        public object GetById(int id)
        {
            return "Success" + id ;
        }

测试结果:

之前博主演示参数和返回值的时候都是使用的匹配到action的路由。这种用法和MVC里面保持一致,比较好理解,但是WebApi里面并不提倡。

2.2、自定义路由二

第二个自定义路由第一眼看上去是不太好理解的,没关系,我们先来按照它的路由模板规则使用试试。

通过http://localhost:21528/testapi/Order/aa/匹配到GetAll()方法

通过http://localhost:21528/testapi/Order/aa/2匹配到的是GetById()方法

通过http://localhost:21528/testapi/Order/bb/2匹配到的也是GetById()方法。

什么意思呢?也就是说,只要{ordertype}按照路由规则去配置,都能找到对应的方法。这里的{ordertype}有什么用呢?这个要留在下面介绍特性路由的时候来解释。

//////////////////

经过上面的学习总结了几个自己的测试用例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MVCWebApi1
{
    ///


    /// 配置WebApi
    ///

    public static class WebApiConfig
    {

        ///


        /// 项目启动后路由配置将调用方法
        ///

        /// 传入路由配置
        public static void Register(HttpConfiguration config)
        {
            //// 启用Web API特性路由
            //config.MapHttpAttributeRoutes();

            //1.默认路由
            config.Routes.MapHttpRoute(
                name: "DefaultApi",//本路由的名称

               routeTemplate: "api/{controller}/{id}",//路由的格式:映射地址+api(可以换名字)+/+controller(控制台的方法)+/+id(传入的值)
              
               // routeTemplate: "login/{controller}/{id}", //测试

               defaults: new { id = RouteParameter.Optional }
                //defaults: new { id = @"\d+"} //必须带参才能访问接口: \d+表示匹配一个或多个数字 、id = @"\d*"表示匹配0个或多个数字(测试失败)
               // defaults: new { controller = "values", id = RouteParameter.Optional } //设置默认值:默认接口(控制器类ValuesController)为values,id默认值为可选(可有可无)。
            );

            // 取消注释下面的代码行可对具有 IQueryable 或 IQueryable 返回类型的操作启用查询支持。
            // 若要避免处理意外查询或恶意查询,请使用 QueryableAttribute 上的验证设置来验证传入查询。
            // 有关详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=279712。
            //config.EnableQuerySupport();

            // 若要在应用程序中禁用跟踪,请注释掉或删除以下代码行
            // 有关详细信息,请参阅: http://www.asp.net/web-api


            //2.自定义路由一:匹配到action
            config.Routes.MapHttpRoute(
                name: "login",
                routeTemplate: "login/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional}
                );


            //3.自定义路由二
            config.Routes.MapHttpRoute(
                name: "TestApi",
                routeTemplate: "api/{controller}/{ordertype}/{id}",
                defaults: new { ordertype = "aa", id = RouteParameter.Optional }
            );


            config.EnableSystemDiagnosticsTracing();
        }
    }
}

/*
 通过上文路由的过程,我们知道,一个请求过来之后,路由主要需要经历三个阶段

根据请求的url匹配路由模板
找到控制器
找到action
 */

 

最后因为

  //[Route("Values/SaveData")] //需要引用包:Microsoft.AspNet.WebApi.Core
        //[HttpPost]
        //public HttpResponseMessage SavaData(object order)
        //{
        //    return Request.CreateResponse();
        //}

这部分引用了一个包然后整个项目就崩溃了

 

 

 

你可能感兴趣的:(MVCAPI)