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

Razor Pages自定义路由优化咨询:替代int?约束方案

嘿,这个问题我之前也踩过坑——你现在用int? id来区分路由的方案确实不够理想,核心问题就是你吐槽的:每次请求都要做整数解析校验,完全是没必要的性能开销,而且路由规则也不够直观,后续维护容易埋下冲突隐患。

问题分析:为什么当前方案不合理?

你依赖int? id的参数约束来区分/1和/ListJson,本质上是让路由系统先尝试把URL片段解析成整数,解析失败才会匹配到ListJson对应的处理器。这就导致:

  • 所有带非数字片段的请求(比如/ListJson)都会先经历一次无效的整数解析,平白增加性能损耗;
  • 如果后续新增类似命名的处理器(比如OnGetDetail),很容易出现路由匹配冲突,维护成本直线上升。
优化方案:精准定义路由模板

最直接的优化思路是给不同处理器绑定明确的、带精准约束的路由模板,让路由系统直接匹配,跳过不必要的类型校验。下面提供两种常用实现方式:

方式1:直接在Razor页面中用@page指定多路由模板

这种方式简单直观,适合页面数量不多的场景。以你的Index.cshtml为例,直接在页面顶部添加多个@page指令:

@page ""          <!-- 匹配路由 "/" -->
@page "{id:int}"  <!-- 匹配路由 "/1" -->
@page "ListJson"  <!-- 匹配路由 "/ListJson" -->
@page "ListJson/{id:int}"  <!-- 匹配路由 "/ListJson/1" -->

@model IndexModel
<!-- 页面内容 -->

对应的PageModel处理器保持不变:

public class IndexModel : PageModel
{
    public void OnGet(int? id)
    {
        // 处理 "/" 和 "/1" 逻辑
    }

    public void OnGetListJson(int? id)
    {
        // 处理 "/ListJson" 和 "/ListJson/1" 逻辑
    }
}

这样路由系统会直接根据模板匹配请求,完全不需要做整数解析来区分路由。

方式2:自定义IPageRouteModelConvention批量配置

如果你的页面数量较多,不想在每个页面重复写@page,可以自定义全局路由约定,批量给处理器绑定路由模板:

public class CustomPageRouteConvention : IPageRouteModelConvention
{
    public void Apply(PageRouteModel model)
    {
        // 遍历页面的所有处理器,为不同方法添加对应路由模板
        var onGetHandler = model.HandlerMethods.FirstOrDefault(h => h.Name == nameof(PageModel.OnGet));
        if (onGetHandler != null)
        {
            // 添加根路由和带int id的路由
            AddSelector(model, "");
            AddSelector(model, "{id:int}");
        }

        var listJsonHandler = model.HandlerMethods.FirstOrDefault(h => h.Name == "OnGetListJson");
        if (listJsonHandler != null)
        {
            // 添加ListJson相关路由
            AddSelector(model, "ListJson");
            AddSelector(model, "ListJson/{id:int}");
        }
    }

    private void AddSelector(PageRouteModel model, string template)
    {
        model.Selectors.Add(new SelectorModel
        {
            AttributeRouteModel = new AttributeRouteModel
            {
                Template = template
            }
        });
    }
}

然后在Program.cs中注册这个约定:

builder.Services.AddRazorPages(options =>
{
    options.Conventions.Add(new CustomPageRouteConvention());
});

这种方式可以统一管理所有页面的路由规则,适合大型项目。

额外建议
  • 尽量避免依赖参数类型来区分路由,路由规则应该是显式、直观的;
  • 对于带参数的路由,始终添加对应的约束(比如{id:int}),既能提高匹配效率,也能避免无效请求进入处理器。

内容的提问来源于stack exchange,提问作者subcoder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:22:58