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

.NET Core API属性路由失效求助:Hosted Blazor WASM服务端路由异常

解决Hosted Blazor WASM服务端Attribute Routing路由不匹配问题

问题现象

在Hosted Blazor WASM项目中,服务端控制器的Attribute Routing出现异常:

  • [Route("api/{controller}")]可正常匹配https://localhost:7237/api/pages/
  • [Route("api/{controller}/{action}")]无法匹配https://localhost:7237/api/pages/something,请求被路由到回退的index.html

原因分析

  1. 路由模板中的{action}默认会尝试匹配控制器方法的名称,但你的方法名为Get,请求URL中的something并非方法名,导致路由无法匹配到目标方法,最终触发回退规则。
  2. [ApiController]特性启用了路由的严格匹配规则,进一步放大了这种不匹配的问题。

解决方案

方案一:修改路由模板参数名

将路由模板中的{action}改为自定义参数名,避免与方法名匹配逻辑冲突:

[ApiController]
public class PagesController : ControllerBase
{
    public PagesController()
    {
    }

    [HttpGet]
    [Route("api/{controller}")]
    [Route("api/{controller}/{actionName}")]
    [Route("api/{controller}/{actionName}/{param}")]
    public async Task<PageVm> Get(string controller, string? actionName, string? param, string? WebsiteId)
    {
        DomainLogic dl = new DomainLogic();
        PageVm PageVm = new PageVm();
        PageVm.WebsiteId = await dl.GetWebsiteIdFromDomainAsync(db, Request);
        
        Console.WriteLine($"{controller} Get() was called with action: {actionName}");
        return PageVm;
    }
}

修改后访问https://localhost:7237/api/pages/something,actionName参数会被正确赋值为something,路由可匹配到Get方法。

方案二:显式绑定路由参数并添加可选约束

保留{action}参数名,通过[FromRoute]显式绑定并添加可选约束,避免与方法名匹配:

[ApiController]
public class PagesController : ControllerBase
{
    public PagesController()
    {
    }

    [HttpGet]
    [Route("api/{controller}")]
    [Route("api/{controller}/{action?}")]
    [Route("api/{controller}/{action?}/{param?}")]
    public async Task<PageVm> Get(string controller, [FromRoute] string? action, [FromRoute] string? param, string? WebsiteId)
    {
        DomainLogic dl = new DomainLogic();
        PageVm PageVm = new PageVm();
        PageVm.WebsiteId = await dl.GetWebsiteIdFromDomainAsync(db, Request);
        
        Console.WriteLine($"{controller} Get() was called with action: {action}");
        return PageVm;
    }
}

?标记参数为可选,[FromRoute]确保参数从路由路径中获取,而非尝试匹配方法名。

方案三:控制器级路由前缀简化配置

在控制器级别添加路由前缀,简化方法路由模板,同时避免冗余参数:

[ApiController]
[Route("api/[controller]")]
public class PagesController : ControllerBase
{
    public PagesController()
    {
    }

    [HttpGet]
    [Route("")]                  // 匹配api/pages
    [Route("{action}")]          // 匹配api/pages/something
    [Route("{action}/{param}")]  // 匹配api/pages/something/123
    public async Task<PageVm> Get([FromRoute] string? action, [FromRoute] string? param, string? WebsiteId)
    {
        string controller = nameof(PagesController).Replace("Controller", "");
        DomainLogic dl = new DomainLogic();
        PageVm PageVm = new PageVm();
        PageVm.WebsiteId = await dl.GetWebsiteIdFromDomainAsync(db, Request);
        
        Console.WriteLine($"{controller} Get() was called with action: {action}");
        return PageVm;
    }
}

这种方式更符合ApiController的路由规范,无需手动传递controller参数。

验证方法

修改代码后重启服务,访问https://localhost:7237/api/pages/something,查看控制台是否输出对应日志,确认请求被控制器方法处理而非回退到index.html。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:50:14