ASP.Net Core 6.0 Razor页面如何获取所有页面的标题与元描述?
解决方案:从Razor页面直接提取标题与元描述信息
核心思路
既然不想维护重复数据,可通过解析Razor页面的.cshtml文件内容提取所需信息——标题和元描述直接写在视图文件中,无需实例化其他页面的PageModel。结合你已通过EndpointDataSource获取的URL,对应到物理文件路径即可完成解析。
具体实现步骤
1. 映射路由到物理文件路径
Razor页面的路由与物理文件存在对应关系:比如路由/Home对应Pages/Home.cshtml,根路由/对应Pages/Index.cshtml。可直接根据路由规则拼接文件路径,或通过ApplicationPartManager获取更精准的映射(适合复杂路由场景)。
2. 编写文件解析类提取元数据
创建一个提取类,读取.cshtml文件内容,用正则匹配ViewData["Title"]和<meta name="description">的内容:
public class RazorPageMetadataExtractor { private readonly IWebHostEnvironment _env; public RazorPageMetadataExtractor(IWebHostEnvironment env) { _env = env; } public (string? Title, string? Description) ExtractMetadata(string pageRoute) { // 路由转物理文件路径 string filePath = pageRoute == "/" ? Path.Combine(_env.ContentRootPath, "Pages", "Index.cshtml") : Path.Combine(_env.ContentRootPath, "Pages", $"{pageRoute.TrimStart('/')}.cshtml"); if (!File.Exists(filePath)) { return (null, null); } string content = File.ReadAllText(filePath); // 匹配ViewData["Title"]的值 var titleMatch = Regex.Match(content, @"ViewData\[""Title""\]\s*=\s*""([^""]+)"""); string? title = titleMatch.Success ? titleMatch.Groups[1].Value : null; // 匹配meta description的content值 var descriptionMatch = Regex.Match(content, @"<meta\s+name=""description""\s+content=""([^""]+)""\s*/?>", RegexOptions.IgnoreCase); string? description = descriptionMatch.Success ? descriptionMatch.Groups[1].Value : null; return (title, description); } }
3. 在首页PageModel中整合数据
注入EndpointDataSource和自定义提取器,遍历Razor页面端点并提取元数据:
public class IndexModel : PageModel { private readonly EndpointDataSource _endpointDataSource; private readonly RazorPageMetadataExtractor _extractor; public List<PageMetadata> Pages { get; set; } = new(); public IndexModel(EndpointDataSource endpointDataSource, RazorPageMetadataExtractor extractor) { _endpointDataSource = endpointDataSource; _extractor = extractor; } public void OnGet() { // 筛选Razor页面类型的端点 var razorEndpoints = _endpointDataSource.Endpoints .OfType<RouteEndpoint>() .Where(e => e.Metadata.GetMetadata<Microsoft.AspNetCore.Mvc.RazorPages.PageMetadata>() != null); foreach (var endpoint in razorEndpoints) { var pageRoute = endpoint.RoutePattern.RawText ?? ""; var (title, description) = _extractor.ExtractMetadata(pageRoute); Pages.Add(new PageMetadata { Url = pageRoute, Title = title ?? "未设置标题", Description = description ?? "未设置描述" }); } } } public class PageMetadata { public string Url { get; set; } = ""; public string Title { get; set; } = ""; public string Description { get; set; } = ""; }
4. 注册服务
在Program.cs中注册提取器:
builder.Services.AddScoped<RazorPageMetadataExtractor>();
性能优化方案
如果担心运行时解析文件的性能损耗,可在编译阶段通过Roslyn分析器收集所有Razor页面的元数据,生成静态类存储信息,运行时直接读取即可。这种方式性能更高,但实现复杂度稍高,适合页面数量较多的场景。
内容的提问来源于stack exchange,提问作者Mike Martin
相关产品推荐
相关产品推荐

