You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:39:20