asp.net core 系列 6 MVC框架路由(下)


一.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 的路由模板。

  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();
        }    

  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();
        }

  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呢,下面使用區域路由來實現:

          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 則符合約束,網頁顯示正常。

 

 

  參考文獻

  官方資料:asp.net core routing

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM