ASP.NET Core Razor 页面路由详解

发布时间 - 2026-01-11 03:05:16    点击率:

 在服务器端 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 映射文件
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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# ASP.NET  # Core  # Razor  # 页面路由  # ASP.NET Core中的Razor页面实现路由功能  # ASP.NET Core中Razor页面与MVC区别介绍  # ASP.NET Core中Razor页面的Handlers处理方法详解  # ASP.NET Core Razor页面用法介绍  # ASP.NET Core中的Razor页面介绍  # asp.net core razor自定义taghelper的方法  # ASP.NET Core 2.0中Razor页面禁用防伪令牌验证  # 如何ASP.NET Core Razor中处理Ajax请求  # ASP.NET Core中的Razor页面使用视图组件  # 您可以  # 如果您  # 应用程序  # 则可  # 第一个  # 将其  # 您在  # 如何将  # 的是  # 都是  # 是一个  # 您的  # 文档  # 就像  # 在此  # 是这样  # 这两个  # 微软  # 自定义  # 非常重要 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 微信小程序 input输入框控件详解及实例(多种示例)  Python文件异常处理策略_健壮性说明【指导】  Laravel如何与Inertia.js和Vue/React构建现代单页应用  android nfc常用标签读取总结  Laravel如何实现数据库事务?(DB Facade示例)  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  Python图片处理进阶教程_Pillow滤镜与图像增强  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  香港服务器租用每月最低只需15元?  HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何制作一个表白网站视频,关于勇敢表白的小标题?  如何在IIS管理器中快速创建并配置网站?  如何正确选择百度移动适配建站域名?  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  中山网站推广排名,中山信息港登录入口?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  b2c电商网站制作流程,b2c水平综合的电商平台?  如何注册花生壳免费域名并搭建个人网站?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  jquery插件bootstrapValidator表单验证详解  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  Laravel如何使用Eloquent进行子查询  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  Java解压缩zip - 解压缩多个文件或文件夹实例  详解Android中Activity的四大启动模式实验简述  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程  zabbix利用python脚本发送报警邮件的方法  Android GridView 滑动条设置一直显示状态(推荐)  Laravel如何使用Vite进行前端资源打包?(配置示例)  如何用免费手机建站系统零基础打造专业网站?  Java垃圾回收器的方法和原理总结  如何在七牛云存储上搭建网站并设置自定义域名?  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  Laravel如何使用Telescope进行调试?(安装和使用教程)  Bootstrap整体框架之CSS12栅格系统  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  如何快速生成可下载的建站源码工具?  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  Swift中循环语句中的转移语句 break 和 continue  如何快速搭建高效WAP手机网站吸引移动用户?