• ASP.NET Core Razor 页面路由


    在服务器端 Web 应用程序框架中,其中非常重要的设计是开发人员如何将URL与服务器上的资源进行匹配,以便正确的处理请求。最简单的方法是将 URL 映射到磁盘上的物理文件,在 Razor 页面框架中,ASP.NET团队就是这样实现的。

    关于 Razor 页面框架如何将 URL 与文件相匹配,有一些规则您必须了解,以及如何根据需要自定义规则改变输出的结果。如果您将 Razor 页面与 Web Form 框架进行比较,您还需要了解取代的 Ur l参数以及在URL中传递数据的机制。

    规则一,Razor 页面需要一个根目录。默认情况下,该根目录是 Pages,位于Web应用程序项目的根目录中。您可以在Startup类的ConfigureServices方法中配置其它文件夹作为根目录。以下是将根目录更改为位于应用程序 “Content” 文件夹:

        public void ConfigureServices(IServiceCollection services)
        { 
            services 
                .AddMvc(). 
                AddRazorPagesOptions(options => { 
                    options.RootDirectory = "/Content";
             }); 
        }
    

    规则二,URL映射到Razor页面,URL不包含文件扩展名。

    规则三,“Index.cshtml”是一个默认文档,这意味着如果URL中缺少文件名,该请求将被映射到指定文件夹中的“Index.cshtml”。以下是一些URL如何映射到文件路径的示例:

    URL 映射文件
    www.domain.com /Pages/Index.cshtml
    www.domain.com/index /Pages/Index.cshtml
    www.domain.com/index /Pages/Index.cshtml
    www.domain.com/account /Pages/account.cshtml 或者 /Pages/account/index.cshtml

    在最后一个例子中,URL映射到两个不同的文件 - 根目录中的“account.cshtml”、“account”文件夹中的“index.cshtml”。Razor 页面框架无法识别要选择哪一个文件,因此如果您在应用程序中实际同时拥有这两个文件,那么如果您尝试浏览www.domain.com/account,会抛出如下异常:

    AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:

    Page: /account/Index

    Page: /account

    URL传递参数

    就像大多数其它框架一样,参数可以作为查询字符串在 URL 中传递,例如:www.domain.com/product?id=1;或者,您可以将其作为路由参数传递,因此上述示例将变为www.domain.com/product/1。URL的一部分必须映射到参数名称,在页面的路由模板来实现的,@page指令的一部分:

    @page "{id}"
    

    该模板告诉框架将页面名称之后URL的第一段作为“id”的路由参数。您可以通过多种方式访问路由参数的值。第一个是使用RouteData字典:

    @page "{id}"
    {
        var productId = RouteData.Values["id"];
    }
    

    或者,您可以向该页面的OnGet()方法添加与路由参数相同名称的参数,并将其值分配给公共属性:

    @page "{id}"
    @{
        @functions{
    
            public int Id { get; set; }
    
            public void OnGet(int id)
            {
                Id = id;
            }
        }
    }
    <p>The Id is @Id</p>
    

    如果您使用的是PageModel,那么是这样实现的:

    using Microsoft.AspNetCore.Mvc.RazorPages;
    
    namespace RazorPages.Pages
    {
        public class ProductModel : PageModel
        {
            public int Id { get; set; }
            public void OnGet(int id)
            {
                Id = id;
            }
        }
    }
    
    @page "{id}"
    @model  ProductModel
    <p>The Id is @Model.Id</p>
    

    最后,您可以在公有属性使用BindProperty特性,并省略该OnGet方法中的参数。Razor 文件内容保持不变,但是PageModel代码略有更改:

    using Microsoft.AspNetCore.Mvc.RazorPages;
    
    namespace RazorPages.Pages
    {
        public class ProductModel : PageModel
        {
            [BindProperty(SupportsGet = true)]
            public int Id { get; set; }
            public void OnGet()
            {
            }
        }
    }
    

    约束

    此外,在此示例中参数的约束是它必须有一个值。URL www.domain.com/product/applewww.domain.com/product/21一样有效,都是可以与路由匹配。如果您希望id值为整数,则可以通过将数据类型添加到模板来指定约束:

    @page "{id:int}"
    

    现在,如果您尝试通过“apple”作为参数值,应用程序将返回404 Not Found状态码。

    您可以指定值不是必需的,可以将参数设置为可为空类型:

    @page "{id:int?}"
    

    如果您的应用程序允许使用“apple”作为参数值,则可以指定只允许使用A-Z和a-z的字符:

    @page "{id:alpha}"
    

    您可以与最小长度要求相结合:

    @page "{id:alpha:minlength(4)}"
    

    更多的约束信息,可以查看微软文档

    友好URL

    友好的URL能够将 URL 映射到磁盘上的任意文件,打破根据文件名一对一的映射关系。您可以使用这个特性来不改变 URL 以进行SEO优化而不能重命名文件的问题,例如,如果希望所有请求由一个文件进行处理。友好 URL 在Startup类型的ConfigureServices方法中配置,调用RazorPagesOption类的AddPageRoute方法。以下示例将 URL www.domain.com/product 映射到Razor 页面 “extras”文件夹“products.cshtml”文件:

        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddMvc()
                .AddRazorPagesOptions(options =>
                {
                    options.Conventions.AddPageRoute("/extras/products", "product");
                });
        }
    

    如果您在 Web Forms 中使用过友好 URL,则应注意AddPageRoute方法的参数顺序与 Web Forms MapPageRoute方法相反,文件路径作为第一个参数。此外,AddPageRoute将路由模板作为第二参数,而不是路由定义,其中任何约束被单独定义。

    最后一个例子说明将所有请求映射到单个文件。如果站点内容存储在特定位置(数据库,Markdown文件),并且由单个文件(例如 “index.cshtml” )负责根据 URL 定位内容,然后将其处理为HTML,则可以执行此操作:

        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddMvc()
                .AddRazorPagesOptions(options => {
                     options.Conventions.AddPageRoute("/index", "{*url}");
            });
        }
    

    路由模板(*)通配符表示“全部”。即使使用此配置,磁盘上的现有文件和URL之间的匹配规则仍然正常运行。

    总结

    Razor 页面中的路由系统非常直观,基于文件位置,但如果需要覆盖默认约定,它也非常强大,可配置。

    原文:《Routing in Razor Pages》https://www.mikesdotnetting.com/article/310/routing-in-razor-pages
    翻译:Sweet Tang
    本文地址:http://www.cnblogs.com/tdfblog/p/razor-pages-route-in-asp-net-core.html
    欢迎转载,请在明显位置给出出处及链接。

  • 相关阅读:
    剑指offer(第2版)刷题 Python版汇总
    git学习笔记
    Python中的lambda、map和filter
    算法题 22 折纸问题 (牛客网,今日头条)
    算法题 21 findNSum (好未来,LeetCode,牛客网)
    算法题 20 或与加
    Python的内存管理机制
    【算法题12 解码方法decode way】
    理解循环神经网络的来龙去脉
    机器学习资源个人汇总
  • 原文地址:https://www.cnblogs.com/tdfblog/p/razor-pages-route-in-asp-net-core.html
Copyright © 2020-2023  润新知