using Dpz.Core.Entity.Base;
using Dpz.Core.Entity.Base.Indexes;

namespace Dpz.Core.Public.Entity.Seo;

/// <summary>
/// Dpz.Core.Web 扫描得到的 MVC 页面路由定义
/// </summary>
public class PageRouteDefinition : BaseEntity, IIndexedEntity<PageRouteDefinition>
{
    /// <summary>
    /// 标准化 Action 路由键,不包含参数值
    /// </summary>
    public required string RouteKey { get; set; }

    /// <summary>
    /// Area 名称
    /// </summary>
    public string? Area { get; set; }

    /// <summary>
    /// Controller 名称
    /// </summary>
    public required string Controller { get; set; }

    /// <summary>
    /// Action 名称
    /// </summary>
    public required string Action { get; set; }

    /// <summary>
    /// HTTP 方法汇总
    /// </summary>
    public List<string> HttpMethods { get; set; } = [];

    /// <summary>
    /// 实际注册的 Endpoint 变体
    /// </summary>
    public List<PageRouteEndpointDefinition> Endpoints { get; set; } = [];

    /// <summary>
    /// 可配置参数
    /// </summary>
    public List<PageRouteParameterDefinition> Parameters { get; set; } = [];

    /// <summary>
    /// 是否仍然存在于最新扫描结果
    /// </summary>
    public bool IsActive { get; set; } = true;

    /// <summary>
    /// 最后扫描时间
    /// </summary>
    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public DateTime LastScannedAt { get; set; } = DateTime.Now;

    /// <inheritdoc />
    public static IReadOnlyList<EntityIndexDefinition> GetIndexDefinitions() =>
        [
            new()
            {
                Fields = [EntityIndexField.Ascending<PageRouteDefinition>(x => x.RouteKey)],
                Unique = true,
            },
            new()
            {
                Fields =
                [
                    EntityIndexField.Ascending<PageRouteDefinition>(x => x.Controller),
                    EntityIndexField.Ascending<PageRouteDefinition>(x => x.Action),
                    EntityIndexField.Ascending<PageRouteDefinition>(x => x.IsActive),
                ],
            },
        ];
}

/// <summary>
/// MVC 页面路由参数定义
/// </summary>
public class PageRouteParameterDefinition
{
    /// <summary>
    /// 参数名称
    /// </summary>
    public required string Name { get; set; }

    /// <summary>
    /// 参数类型
    /// </summary>
    public string? TypeName { get; set; }

    /// <summary>
    /// 参数来源
    /// </summary>
    public PageRouteParameterSource Source { get; set; }

    /// <summary>
    /// 是否可选
    /// </summary>
    public bool IsOptional { get; set; }
}

/// <summary>
/// MVC Action 对应的实际 Endpoint 定义
/// </summary>
public class PageRouteEndpointDefinition
{
    /// <summary>
    /// 路由名称
    /// </summary>
    public string? RouteName { get; set; }

    /// <summary>
    /// 路由模板
    /// </summary>
    public required string Template { get; set; }

    /// <summary>
    /// HTTP 方法
    /// </summary>
    public List<string> HttpMethods { get; set; } = [];

    /// <summary>
    /// 路由默认值
    /// </summary>
    public Dictionary<string, string> Defaults { get; set; } = [];

    /// <summary>
    /// 路由必需值
    /// </summary>
    public Dictionary<string, string> RequiredValues { get; set; } = [];
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个用于存储和管理 ASP.NET Core MVC 页面路由定义的实体类文件,主要用于 SEO(搜索引擎优化)相关功能。

主要类结构

1. PageRouteDefinition (主实体类)

这是核心实体类,继承自 BaseEntity 并实现了 IIndexedEntity 接口,用于存储 MVC 路由的完整定义信息。

关键属性:

  • RouteKey: 标准化的路由键(不含参数值),作为唯一标识
  • Area/Controller/Action: MVC 三层路由结构的组成部分
  • HttpMethods: 支持的 HTTP 方法列表(GET、POST 等)
  • Endpoints: 该路由的所有实际 Endpoint 变体(一个 Action 可能对应多个路由模板)
  • Parameters: 该路由接受的参数定义列表
  • IsActive: 标记该路由是否仍在最新扫描中存在(用于检测已删除的路由)
  • LastScannedAt: 最后一次扫描时间

数据库索引定义:

GetIndexDefinitions()

定义了两个索引:

  1. RouteKey 的唯一索引(用于快速查找和去重)
  2. Controller + Action + IsActive 的复合索引(用于按控制器/动作筛选)

2. PageRouteParameterDefinition (参数定义)

描述路由参数的详细信息:

  • Name: 参数名称
  • TypeName: 参数类型(如 "int", "string" 等)
  • Source: 参数来源(枚举类型,可能是 Query、Route、Body 等)
  • IsOptional: 是否为可选参数

3. PageRouteEndpointDefinition (Endpoint 定义)

表示一个具体的路由端点配置:

  • RouteName: 路由名称(可为空)
  • Template: 路由模板(如 "/api/users/{id}"
  • HttpMethods: 该 Endpoint 支持的 HTTP 方法
  • Defaults: 路由默认值字典
  • RequiredValues: 路由必需值字典

使用场景

这个设计典型用于:

  1. 路由扫描系统:自动扫描应用程序中所有的 MVC 路由
  2. SEO 管理:为每个路由配置 SEO 元数据(标题、描述等)
  3. 路由变更检测:通过 IsActive 字段跟踪路由的增删
  4. 动态路由文档:生成 API 文档或站点地图

技术要点

  • 使用 MongoDB(BsonDateTimeOptions 特性)
  • 采用 required 关键字(C# 11+)强制初始化必需属性
  • 使用集合初始化器 = [](C# 12+)
  • 支持数据库索引优化查询性能
评论加载中...