如何在ASP.NET Razor Pages中实现不依赖文件夹结构的RedirectToPage?
问题
我有一个使用内部重定向的ASP.NET Core MVC应用,目前正在研究Razor Pages。先说明我在MVC控制器中的重定向实现方式:
return RedirectToAction( nameof(ControllerNameController.ActionName), nameof(ControllerNameController).GetControllerName());
其中.GetControllerName()是移除类名Controller后缀的扩展方法。该方式支持自由重命名控制器与操作,重构会自动更新引用,且基于属性路由,不依赖控制器的文件夹层级。
现在我想将部分控制器迁移到Razor Pages(PageModel),但使用RedirectToPage()时难以复用类似方案。目前重定向需指定完整路径,例如:
return RedirectToPage("/Section1/Section2/PageName");
这要求对应文件夹结构为:
- Section1 (文件夹) - Section2 (文件夹) PageName.cshtml (文件)
此方式的问题是,若文件夹结构变更,所有字符串形式的页面引用都需手动更新,重构无法生效。不过可通过@page "/section1/section2/pagename"固定页面URL,无需关心文件位置。
我的问题是:能否实现类似MVC的重定向方式,即通过引用Razor Page类,从@page指令获取URL,而非依赖严格的文件夹结构?
更新1:
若我理解有误请纠正,问题本质可能在于:MVC先调用控制器再调用视图,Razor Pages则先调用视图再根据@model创建页面模型。若此逻辑正确,我想要的效果似乎无法实现。
实现方案
可以通过自定义扩展方法结合反射,实现基于PageModel类型的强类型重定向,自动从@page指令配置的路由中获取目标URL,具体步骤如下:
1. 编写自定义扩展方法
创建针对ControllerBase和PageModel的扩展方法,通过反射提取PageModel关联的页面路由:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.Reflection; public static class PageRedirectExtensions { public static RedirectToPageResult RedirectToPage<TModel>(this ControllerBase controller) where TModel : PageModel { var pageRoute = GetPageRouteFromModel<TModel>(); return controller.RedirectToPage(pageRoute); } public static RedirectToPageResult RedirectToPage<TModel>(this PageModel pageModel) where TModel : PageModel { var pageRoute = GetPageRouteFromModel<TModel>(); return pageModel.RedirectToPage(pageRoute); } private static string GetPageRouteFromModel<TModel>() where TModel : PageModel { // 查找当前PageModel类型上的PageAttribute(对应@page指令配置) var pageAttr = typeof(TModel).GetCustomAttribute<PageAttribute>(); if (pageAttr != null && !string.IsNullOrEmpty(pageAttr.Route)) { // 返回@page指定的路由,确保以/开头 return pageAttr.Route.StartsWith("/") ? pageAttr.Route : $"/{pageAttr.Route}"; } // 降级处理:未配置@page路由时,从PageModel类名推导页面路径 var modelName = typeof(TModel).Name; var pageName = modelName.EndsWith("Model") ? modelName.Substring(0, modelName.Length - 5) : modelName; return $"/{pageName}"; } }
2. 强类型调用重定向
在MVC控制器或Razor PageModel中,直接通过PageModel类型调用扩展方法:
// MVC控制器中重定向到指定PageModel对应的页面 return this.RedirectToPage<OrderDetailModel>(); // Razor PageModel中重定向到另一个PageModel对应的页面 return RedirectToPage<UserProfileModel>();
关键说明
- 必须确保目标
.cshtml页面配置了@page "/xxx/xxx"路由,扩展方法会优先读取该路由,完全脱离文件夹结构依赖 - 重命名PageModel类时,编译器会自动更新所有引用,无需手动修改路径字符串
- 若未配置
@page路由,扩展方法会自动从PageModel类名推导页面路径(需保证类名与页面文件名一致,如OrderDetailModel对应OrderDetail.cshtml)
内容的提问来源于stack exchange,提问作者Crypt32

