欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net core 系列 6 路由(中)

程序员文章站 2022-03-25 18:57:27
一.URL 生成 接着上篇讲MVC的路由,MVC 应用程序可以使用路由的 URL 生成功能,生成指向操作的 URL 链接。 生成 URL 可消除硬编码 URL,使代码更稳定、更易维护。 此部分重点介绍 MVC 提供的 URL 生成功能,并且仅涵盖 URL 生成工作原理的基础知识。 IUrlHelpe ......

一.url 生成

  接着上篇讲mvc的路由,mvc 应用程序可以使用路由的 url 生成功能,生成指向操作的 url 链接。 生成 url 可消除硬编码 url,使代码更稳定、更易维护。 此部分重点介绍 mvc 提供的 url 生成功能,并且仅涵盖 url 生成工作原理的基础知识。 iurlhelper 接口用于生成 url,是 mvc 与路由之间的基础结构的基础部分。 在控制器、视图和视图组件中,可通过 url 属性找到 iurlhelper 的实例。

        //
        // mvc 框架的controllerbase类下
        //摘要:
        //     gets or sets the microsoft.aspnetcore.mvc.iurlhelper.
        public iurlhelper url { get; set; }

  

  1.1 传统路由下的url生成

    下面示例中,通过使用iurlhelper接口在index页面生成指向另一操作destination的 url超连接。

        [route("home/index")]
        public iactionresult index()
        {
            // generates /home/destination
            var url = url.action("destination");
            var urladdress = "<a href=\"" + url + "\"  >click on to the destination</a>";
            viewdata["url"] = urladdress;
            return view();
        }

        public iactionresult destination()
        {
            return view();
        }

       // index.cshtml     
      @html.raw(viewdata["url"].tostring())

    当加载index页面后,点击超连接"click on to the destination" 将进入后台控制器的destination操作中。

    上面的 url.action 示例假定使用传统路由,但 url 生成功能的工作方式与属性路由相似,只不过概念不同。 在传统路由中,路由值用于扩展模板。controller 和 action 的路由值通常出现在该模板中, 这种做法可行是因为通过路由匹配的 url 遵守某项约定。 这里的扩展模板指的是routes.maproute来添加路由规则约定。

 

  1.2 属性路由下的url生成

    在属性路由中,controller 和 action 的路由值不能出现在模板中(也就是不会使用routes.maproute),它们用于查找要使用的模板。

      //首先不用传统路由,去掉了routes.maproute
      public void configure(iapplicationbuilder app)
        {
            app.usemvc();
        }

        [route("")]
        public iactionresult index()
        {
            // generates /custom/url/to/destination 
            var url = url.action("destination");
            var urladdress = "<a href=\"" + url + "\"  >"+url+"</a>";
            viewdata["url"] = urladdress;
            return view();
        }

        [httpget("custom/url/to/destination")]
        public iactionresult destination()
        {
            return view();
        }
    

     生成如下图所示 :所以会生成与httpget配置的路径一样,是因为属性路由下的url生成,它们用于查找要使用的模板。mvc 生成一个包含所有属性路由操作的查找表,并匹配 controller 和 action 的值,以选择要用于生成 url 的路由模板。

asp.net core 系列 6 路由(中)

  1.3 根据action名称生成 url

    url.action (iurlhelper . action) 以及所有相关重载都基于这样一种想法:用户想通过指定控制器名称和操作名称来指定要链接的内容。

        [route("")]
        public iactionresult index()
        {
            // generates /home/destination/1?color=red
            var url = url.action("destination","home",new  { id=1 , color="red"});
            var urladdress = "<a href=\"" + url + "\"  >" + url + "</a>";
            viewdata["url"] = urladdress;
            return view();
        }

       
        public iactionresult destination(int id,string color)
        {
            return view();
        }    

asp.net core 系列 6 路由(中)

  1.4 根据路由名称生成 url

    iurlhelper 还提供 url.routeurl 系列的方法。 这些方法类似于 url.action。url.routeurl 指定一个路由名称,以使用特定路由来生成 url,通常不指定控制器或操作名称。

        [route("")]
        public iactionresult index()
        {
            // generates /custom/url/to/destination
            var url = url.routeurl("destination_route");
            var urladdress = "<a href=\"" + url + "\"  >click on to the destination</a>";
            viewdata["url"] = urladdress;
            return view();
        }

        [httpget("custom/url/to/destination", name = "destination_route")]
        public iactionresult destination()
        {
            return view();
        }

asp.net core 系列 6 路由(中)

  1.5  其它生成

     (1)在 html 中生成 url: ihtmlhelper 提供 htmlhelper 方法 html.beginform 和 html.actionlink,可分别生成 <form> 和 <a>元素。 这些方法使用 url.action 方法来生成 url,并且采用相似的参数。

    (2)在action中重定向:redirecttoaction("index"); 

 

二. area区域路由

    区域是一种 mvc 功能,用于将相关功能整理到一个组中,作为单独的路由命名空间(用于控制器操作)和文件夹结构(用于视图)。 通过使用区域,应用程序可以有多个名称相同的控制器,只要它们具有不同的区域。 通过向 controller 和 action 添加另一个路由参数 area,可使用区域为路由创建层次结构。

    下面是mvc文件结构,对于users控制器,在视图层多了一级manage文件夹。如何使users控制器中adduser操作关联adduser.cshtml呢,下面使用区域路由来实现:

asp.net core 系列 6 路由(中)

          app.usemvc(routes =>
            {
                //用于名为 blog 的区域
                routes.maparearoute("blog_route", "blog","manage/{controller}/{action}/{id?}");
                /*
                 * 注释的maproute与上面的区域路由作用一样
                routes.maproute("blog_route", "manage/{controller}/{action}/{id?}",
                defaults: new { area = "blog" }, constraints: new { area = "blog" });
                */
                routes.maproute(
                    name: "default",
                    template: "{controller=home}/{action=index}/{id?}");
            });
        //控制器上应用区域路由
       [area("blog")]      public class userscontroller : controller      {    // get: /<controller>/      public iactionresult adduser()      {   return view();      }      }

    在浏览器中输入/manage/users/adduser 将自动进入adduser()中,这是因为当前路由:manage/{controller}/{action}/{id?}符合blog模板,所以使用blog区域路由。

  

 三. iactionconstraint 路由约束

    实现iactionconstraint最简单的方法是创建派生自 system.attribute 的类,并将其置于操作和控制器上。mvc 将自动发现任何应用属性iactionconstraint的操作和控制器。

    在下面的示例中,约束基于路由数据中的国家/地区代码选择操作,开发人员负责实现accept 方法,当路由中id值为en-us时accept 方法返回 true 以表示该操作是匹配项,一切按正常解析返回客户端。 如果accept 方法返回false将不执行iactionconstraint标记的action,向客户端返回404错误。

//定义actionconstraint属性约束
public class countryspecificattribute : attribute, iactionconstraint
    {
        private readonly string _countrycode;

        public countryspecificattribute(string countrycode)
        {
            _countrycode = countrycode;
        }

        public int order
        {
            get
            {
                return 0;
            }
        }

        public bool accept(actionconstraintcontext context)
        {
            return string.equals(
                context.routecontext.routedata.values["id"].tostring(),
                _countrycode,
                stringcomparison.ordinalignorecase);
        }
    }
      //应用路由的action约束,并且路由中id值为en-us
       [countryspecific("en-us")]
        public iactionresult privacy(string countrycode)
        {
            return view();
        }

    在浏览器测试时:如果输入http://localhost:30081/home/privacy/zh-cn,则网页显示404。如果输入http://localhost:30081/home/privacy/en-us 则符合约束,网页显示正常。

 

 

  参考文献

  官方资料: