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

ASP.NET Core路由可选参数疑问:未传参时RouteValues为何不含id键

ASP.NET Core路由可选参数的工作机制解析

问题场景

你定义了如下包含可选参数的路由:

app.Map("products/details/{id?}", async context =>
{
    if (context.Request.RouteValues.ContainsKey("id"))
    {
        string? idValue = context.Request.RouteValues["id"] as string;
        bool isInt = long.TryParse(idValue, out long id);
        if (isInt)
        {
            await context.Response.WriteAsync($"Products details - {id}");
        }
        else
        {
            await context.Response.WriteAsync("Needs to be a number");
        }
    }
    else
    {
        await context.Response.WriteAsync("Products details - id is not supplied.");
    }
});

预期未提供id时,RouteValues中仍保留id键且值为null,但实际ContainsKey("id")返回false,触发else代码块。

机制解析

在ASP.NET Core路由系统中,带?的可选路由参数未被提供时,不会被加入RouteValues集合,这是路由匹配的设计规则:

  • 当访问products/details时,路由系统匹配的是去掉可选参数段的路径模板,此时该可选参数并未参与匹配过程,因此不会在RouteValues中生成对应的键值对;
  • 只有当URL中存在对应参数段的内容(比如products/details/123)时,路由系统才会将id键和对应值加入RouteValues。

优化处理方案

不用提前判断ContainsKey,直接从RouteValues取值即可——不存在的键会返回null,可以简化代码:

app.Map("products/details/{id?}", async context =>
{
    string? idValue = context.Request.RouteValues["id"] as string;
    if (!string.IsNullOrEmpty(idValue) && long.TryParse(idValue, out long id))
    {
        await context.Response.WriteAsync($"Products details - {id}");
    }
    else if (!string.IsNullOrEmpty(idValue))
    {
        await context.Response.WriteAsync("Needs to be a number");
    }
    else
    {
        await context.Response.WriteAsync("Products details - id is not supplied.");
    }
});

如果需要强制RouteValues中始终存在id键,可以给可选参数设置默认值,修改路由模板为:

products/details/{id:long?=0}

此时未传参时RouteValues["id"]会返回默认值0,对应的键也会存在,适合需要固定参数存在的业务场景。


内容的提问来源于Stack Exchange,提问作者Mohamed Taha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:00:00