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

自定义MVC Controller无法调用,但模板Controller正常问题求助

问题描述

我找不到问题出在哪。我用JavaScript的fetch()调用自己新建的Controller,项目是基于React模板的MVC 5,使用.NET 6.0框架。默认的WeatherForecastController通过fetch调用能正常触发,但按同样实现创建的DatabaseController却调用不了。网络调试器显示请求返回OK,但直接在浏览器访问这个Controller时,似乎没有对应的路由,也没返回JSON数据。我只是想创建一个能从中层获取数据的新Controller,命名规范是对的,Controller名称以Controller结尾。

默认模板控制器的JS调用

async populateWeatherData() {
    const response = await fetch('weatherforecast');
    const data = await response.json();
    this.setState({ forecasts: data, loading: false });
}

默认模板控制器代码

using Microsoft.AspNetCore.Mvc;

namespace ReactTest.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

新控制器的JS调用

async populateWeatherData() {
    const response = await fetch('database');
    const data = await response.json();
    this.setState({ forecasts: data, loading: false });
}

新控制器实现代码

using Microsoft.AspNetCore.Mvc;

namespace ReactTest.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class DatabaseController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<DatabaseController> _logger;

        public DatabaseController(ILogger<DatabaseController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

当前路由配置

app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");

我试过各种方法,没修改默认路由(新Controller和模板Controller在同一文件夹,应该不是路由问题)。直接访问DatabaseController时没有对应路由,也不返回JSON数据,到底哪里错了?已经查过文档,没找到解决办法。


解决方法
  1. 补全API路由注册
    .NET 6中API控制器需要额外激活属性路由,你的配置里只有MVC的默认路由,缺少API路由的映射。修改Program.cs:

    // 注册控制器服务
    builder.Services.AddControllers();
    
    // 在中间件添加API路由映射,放在MapControllerRoute前后都可以
    app.MapControllers();
    

    默认的WeatherForecast能工作是因为模板自动添加了这部分,新建控制器后需要确保这两步没遗漏。

  2. 检查WeatherForecast类的访问权限
    如果WeatherForecast是默认的internal类(模板中可能定义在WeatherForecastController文件内部),控制器返回时会序列化失败,导致没有有效JSON返回。把它改成public类:

    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
    
  3. 清理重建项目
    有时候.NET编译缓存会导致新控制器无法被识别,右键项目选择「清理」,再重新「生成」后启动调试。

  4. 修正fetch路径
    确保请求路径是根相对路径,避免页面嵌套导致相对路径错误,把fetch('database')改成fetch('/database')(前面加斜杠)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:15:36