ASP.NET Core中调试页面路径:验证Razor页面是否存在
问题
在MVC控制器的Post方法中调用RedirectToPage跳转Razor页面时,因页面相对路径错误,未跳转到目标页面反而进入了Get方法。需要在调用RedirectToPage前后验证指定路径的Razor页面是否存在。
曾尝试以下代码检测页面存在性,但无有效异常直接运行失败:
var user = await _userManager.GetUserAsync(User); var pageLoader = HttpContext.RequestServices.GetService(typeof(PageLoader)) as PageLoader; var pad = new PageActionDescriptor(); pad.RelativePath = "/Path/To/Razor/Page"; var page = await pageLoader.LoadAsync(pad);
理想需求是实现如下伪代码的功能:
var isValidPath = ValidateRazorPage("Path/To/Page", "PageAreaGoesHere"); if(isValidPath) return RedirectToPage("Path/To/Page", new {area= "PageAreaGoesHere"}); else DoErrorHandlingToFigureOutIssue();
解决方案
通过注入IActionDescriptorCollectionProvider可实现Razor页面的存在性验证,具体步骤如下:
1. 注入依赖
在控制器的构造函数中注入IActionDescriptorCollectionProvider:
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider; public YourController(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider) { _actionDescriptorCollectionProvider = actionDescriptorCollectionProvider; }
2. 实现验证方法
编写ValidateRazorPage方法,标准化路径后匹配已注册的Razor页面描述符:
private bool ValidateRazorPage(string pagePath, string areaName = null) { // 标准化页面路径:补全开头斜杠和.cshtml后缀 var normalizedPath = !pagePath.StartsWith("/") ? $"/{pagePath}" : pagePath; normalizedPath = normalizedPath.EndsWith(".cshtml") ? normalizedPath : $"{normalizedPath}.cshtml"; // 筛选所有Razor页面的Action描述符 var pageDescriptors = _actionDescriptorCollectionProvider.ActionDescriptors.Items .OfType<PageActionDescriptor>(); if (!string.IsNullOrEmpty(areaName)) { // 匹配指定区域的页面 return pageDescriptors.Any(p => p.RelativePath.Equals(normalizedPath, StringComparison.OrdinalIgnoreCase) && p.RouteValues.TryGetValue("area", out var pageArea) && pageArea.Equals(areaName, StringComparison.OrdinalIgnoreCase)); } else { // 匹配非区域页面 return pageDescriptors.Any(p => p.RelativePath.Equals(normalizedPath, StringComparison.OrdinalIgnoreCase) && !p.RouteValues.ContainsKey("area")); } }
3. 调用验证方法
在控制器Post方法中直接使用验证逻辑:
var isValidPath = ValidateRazorPage("Path/To/Page", "PageAreaGoesHere"); if(isValidPath) { return RedirectToPage("Path/To/Page", new { area = "PageAreaGoesHere" }); } else { // 自定义错误处理,如返回错误页、记录日志等 return BadRequest("指定的Razor页面不存在"); }
注意事项
- 路径匹配不区分大小写,符合ASP.NET Core路由规则
- 方法自动处理路径标准化,无需手动补全斜杠或
.cshtml后缀 - 区域页面必须传入正确的区域名称,否则无法匹配
内容的提问来源于stack exchange,提问作者Kolichikov
相关产品推荐
相关产品推荐

