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

Razor类库中REST API控制器调用报404,路由未生成URL求助

问题:Razor类库(RCL)中Area内的API控制器调用返回404错误

我在外部程序集(Razor类库,RCL)中部署的REST API控制器无法正常工作,通过JavaScript调用时始终返回404错误。

项目结构:
项目结构

控制器代码:

namespace Case.Coding.Areas.CaseCoding.Controllers
{
    [Route("CaseCoding/[controller]")]
    [ApiController]
    public class LookupsController : ControllerBase
    {
        [HttpPost]
        [Route("External")]
        public async Task<IActionResult> ExternalAsync()
        {
            return Ok("This is a value. Hoo boy.");
        }
    }
}

前端调用代码:
HTML部分:

<button id="ClickHere" onclick="GetApiResult();">Click Here</button>
<div id="ClickResult"></div>

JavaScript部分:

function GetApiResult() {
    var container = $('#ClickResult');
    
    $.ajax({
        url: '/CaseCoding/Lookups/External',
        method: 'POST',
        contentType: 'application/json'
    })
        .done(function (result, statusText, xhr) {
            var isUndefined = typeof result === 'undefined';
    
            if (isUndefined || result.length == 0) {
                container.append('<p class="pat-comment err">Nothing returned.</p>');
            }
            else {
                container.append(result);
            }
        })
        .fail(function (xhr, statusText, err) {
            container.append('<p class="pat-comment err">' + err + '</p>');
        });
    }

调试路由结果:
在启动代码中添加路由调试代码:

if (app.Environment.IsDevelopment())
{
    app.MapGet("/debug/routes", (IEnumerable<EndpointDataSource> endpointSources) =>
        string.Join("\n", endpointSources.SelectMany(source => source.Endpoints)));
}

访问/debug/routes得到结果:

/Error
/Index
/Index
/Privacy
/Page1
Case.Coding.Areas.CaseCoding.Controllers.LookupsController.ExternalAsync (Case.Coding)
HTTP: GET /debug/routes

可以看到API控制器已被列出,但未生成对应的URL。请问这是什么原因?如何让控制器路由被识别为可被JavaScript调用的URL?


解决方案

原因分析

Razor类库中的Area API控制器需要在主项目中显式注册Area路由,同时要保证API路由的配置顺序正确,否则路由系统无法解析对应的URL。

具体步骤

  1. 在主项目中注册Area路由
    在主项目的Program.cs中,确保在注册API路由之前添加Area路由映射:

    app.UseEndpoints(endpoints =>
    {
        // 先注册Area路由
        endpoints.MapControllerRoute(
            name: "areas",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
        
        // 再注册API控制器路由
        endpoints.MapControllers();
        
        // 其他路由(如Razor Pages等)
        endpoints.MapRazorPages();
    });
    

    注意:Area路由必须在MapControllers之前注册,否则Area内的API控制器路由会被忽略。

  2. 完善控制器的Area标识
    给控制器添加[Area]特性,让路由系统明确识别其所属Area,避免解析歧义:

    [Area("CaseCoding")]
    [Route("[area]/[controller]")]
    [ApiController]
    public class LookupsController : ControllerBase
    {
        [HttpPost("External")]
        public async Task<IActionResult> ExternalAsync()
        {
            return Ok("This is a value. Hoo boy.");
        }
    }
    
  3. 确认RCL项目配置
    检查RCL项目的csproj文件,确保包含以下配置,保证控制器能被主项目发现:

    <PropertyGroup>
      <TargetFramework>net6.0</TargetFramework>
      <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
    </PropertyGroup>
    
  4. 验证路由生效
    重启应用后,再次访问/debug/routes,应该能看到类似POST /CaseCoding/Lookups/External的路由条目,此时前端调用即可正常获取响应。

内容的提问来源于stack exchange,提问作者hermes the goat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:00:48