为何ASP.NET React模板中新增的Controller无法正常工作?
核心原因分析
你的问题本质是请求路径不匹配API路由,触发了ASP.NET Core的 fallback 机制返回index.html,而weatherforecast请求正常是因为它的路径恰好匹配了后端的API路由。具体场景如下:
1. 前端相对路径导致请求URL错误
当React应用处于某个子路由(比如http://localhost:3000/counter)时,使用相对路径fetch('different')会生成请求URL:http://localhost:3000/counter/different。这个路径在后端既没有对应的API路由(你的API路由是/different),也没有对应的静态文件,因此触发MapFallbackToFile返回index.html。
而weatherforecast请求正常,大概率是你在React根路径(http://localhost:3000/)下发起的请求,此时相对路径fetch('weatherforecast')会生成http://localhost:3000/weatherforecast,恰好匹配后端的API路由。
2. 前端代理配置限制(可能性较低)
默认的dotnet new react模板会配置前端代理转发请求到后端,但如果自定义了代理规则(比如仅转发/api/*前缀的请求),那么different请求不会被代理到后端,而是被前端服务器当作React路由处理,直接返回index.html。
验证与解决步骤
步骤1:确认实际请求URL
打开浏览器开发者工具(F12)→ 切换到Network标签,发起请求后查看different请求的完整URL:
- 如果URL是子路径下的(比如
/counter/different),说明是相对路径问题。 - 如果URL是
/different但仍返回index.html,直接访问后端地址(比如https://localhost:5001/different):- 不能返回JSON:检查控制器是否为
public类、是否在项目程序集内,以及路由特性是否正确([Route("[controller]")]+[HttpGet]组合生成GET /different路由)。 - 能返回JSON:说明是前端代理或请求路径的问题。
- 不能返回JSON:检查控制器是否为
步骤2:修复请求路径
将前端的相对路径改为绝对路径,确保无论当前处于哪个React路由,都请求后端的根路径API:
async populateWeatherData() { // 加上斜杠使用绝对路径 const differentResponse = await fetch('/different'); const differentData = await differentResponse.text(); // 建议weatherforecast也改为绝对路径避免后续问题 const response = await fetch('/weatherforecast'); const data = await response.json(); this.setState({ forecasts: data, loading: false }); }
步骤3:检查代理配置(若有自定义)
如果修改路径后仍有问题,检查项目根目录package.json中的proxy字段,确保它指向正确的后端地址(比如"proxy": "https://localhost:5001")。如果使用了setupProxy.js自定义代理规则,需添加对/different路径的转发配置:
const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { app.use( ['/weatherforecast', '/different'], createProxyMiddleware({ target: 'https://localhost:5001', changeOrigin: true, }) ); };
内容的提问来源于stack exchange,提问作者FriendlyGhost

