C#进阶之WebAPI(三)

今天复习一下WebAPI的路由知识:

首先分析一下MVC路由和WebAPI路由的区别

在mvc里,默认的路由机制是通过URL路径去匹配控制器和Action方法的,在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 = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

在webapi里,默认的路由机制是通过URL路径去匹配控制器,然后通过http的方法去匹配Action的,在WebAPI中的默认路由定义在App_Start文件夹下的WebApiConfig.cs文件下:

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务

            // Web API 路由
            config.MapHttpAttributeRoutes();

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

WebApi的路由基础:

将MapHttpRoute方法转定义有4个重载的方法:

 //
        // 摘要:
        //     映射指定的路由模板。
        //
        // 参数:
        //   routes:
        //     应用程序的路由的集合。
        //
        //   name:
        //     要映射的路由的名称。
        //
        //   routeTemplate:
        //     路由的路由模板。
        //
        // 返回结果:
        //     对映射路由的引用。
        public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate);
        //
        // 摘要:
        //     映射指定的路由模板并设置默认路由值。
        //
        // 参数:
        //   routes:
        //     应用程序的路由的集合。
        //
        //   name:
        //     要映射的路由的名称。
        //
        //   routeTemplate:
        //     路由的路由模板。
        //
        //   defaults:
        //     一个包含默认路由值的对象。
        //
        // 返回结果:
        //     对映射路由的引用。
        public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults);
        //
        // 摘要:
        //     映射指定的路由模板并设置默认路由值和约束。
        //
        // 参数:
        //   routes:
        //     应用程序的路由的集合。
        //
        //   name:
        //     要映射的路由的名称。
        //
        //   routeTemplate:
        //     路由的路由模板。
        //
        //   defaults:
        //     一个包含默认路由值的对象。
        //
        //   constraints:
        //     一组表达式,用于指定 routeTemplate 的值。
        //
        // 返回结果:
        //     对映射路由的引用。
        public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints);
        //
        // 摘要:
        //     映射指定的路由模板并设置默认的路由值、约束和终结点消息处理程序。
        //
        // 参数:
        //   routes:
        //     应用程序的路由的集合。
        //
        //   name:
        //     要映射的路由的名称。
        //
        //   routeTemplate:
        //     路由的路由模板。
        //
        //   defaults:
        //     一个包含默认路由值的对象。
        //
        //   constraints:
        //     一组表达式,用于指定 routeTemplate 的值。
        //
        //   handler:
        //     请求将被调度到的处理程序。
        //
        // 返回结果:
        //     对映射路由的引用。
        public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler);

看看每个参数的作用:

name:表明路由的名称,注册多个路由时保证不重复就行;

routeTemplate:路由匹配规则。默认是“api/{controller}/{id}”,前面的api是用来区分mvc路由的,不是必选项,是可变的,{controller}是控制器的占位符,{id}是形参的占位符;

defaults:一个包含默认路由值的对象,可以设置controller的默认值;

constraints:对形参的约束;



注册的路由是按照注册先后的顺序进行匹配的,注册越靠前,优先级越大

我们知道,WebApi是符合RESTful风格的,那么如果在一个控制器内部,我们需要提供多个相同的http方法,相同参数的接口我们应该怎么解决呢?

1:活用[Route("")]

在相同请求方法的action的前面可以加上[Route]路由特性进行区分:

/// <summary>
/// 这里可以通过http://localhost:xxxx/api/Values对这个action进行访问
/// </summary>
/// <returns></returns>
public IEnumerable<string> Get1()
{
return new string[] { "value1", "value2" };
}
/// <summary>
/// 这里可以通过http://localhost:xxxx/apis/Values/qqqqq对这个action进行访问
/// </summary>
/// <returns></returns>
[Route("apis/Values/qqqqq")]
public IEnumerable<string> Get2()
{
return new string[] { "value3", "value4" };
}


 和朋友聊了一下,发现这个做法本身就和RESTful风格相抵触,所以就不深究了,一般是对action进行重载,而不是在这上面想办法。
原文地址:https://www.cnblogs.com/yuchenghao/p/10620782.html