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

ASP.NET Core+React项目中Fetch无法返回JSON(404错误)排查

ASP.NET Core + React 404问题排查方案

问题描述

我有一个基于React前端和ASP.NET Core后端的项目,已定义Customers模型、CustomersController控制器、React的Customers组件,以及DatabaseConnection中的GetAllCustomers方法。但前端调用fetch('customers')时返回404 Not Found,响应类型为HTML,无法获取JSON数据,需排查问题。

模型代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace drivingSchoolManagement.Models
{
    [Serializable]
    public class Customers
    {
        public int Id { get; set; }
        public string First_name { get; set; }
        public string Last_name { get; set; }
        public string Address { get; set; }
        public string Zip { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public bool Is_active { get; set; }
    }
}

控制器代码

using drivingSchoolManagement.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace drivingSchoolManagement.Controllers
{
    [ApiController]
    [Route("[controller]")]
    [Produces("application/json")]
    public class CustomersController : ControllerBase
    {
        private readonly ILogger<CustomersController> _logger;
        private readonly DatabaseConnection _dbConnection;

        public CustomersController(ILogger<CustomersController> logger, DatabaseConnection dbConnection)
        {
            _logger = logger;
            _dbConnection = dbConnection;
        }

        [HttpGet]
        public JsonResult Get()
        {
            return new JsonResult(_dbConnection.GetAllCustomers());
        }

    }
}

React组件代码

import React, { Component } from 'react';

export class Customers extends Component {
    static displayName = Customers.name;

    constructor(props) {
        super(props);
        this.state = { customers: [] };

        this.getCustomers();
    }

    async getCustomers() {
        try {
            const response = await fetch('customers', {
                headers: {
                    Accept: 'application/json',
                },
            });
            console.log(response);
            if (!response.ok) {
                throw new Error(response.statusText);
            }
            const data = await response.json();
            this.setState({ customers: data });
        } catch (error) {
            console.log(error);
        }
    }


    render() {
        const customers = this.state.customers.map(customer => {
            return (
                <div key={customer.id}>
                    <p>ID: {customer.id}</p>
                    <p>First name: {customer.first_name}</p>
                    <p>Last name: {customer.last_name}</p>
                    <p>Address: {customer.address}</p>
                    <p>Zip: {customer.zip}</p>
                    <p>Phone: {customer.phone}</p>
                    <p>Email: {customer.email}</p>
                    <p>Is active: {customer.is_active ? 'Yes' : 'No'}</p>
                </div>
            );
        });

        return (
            <div>
                <h1>Customers</h1>
                {customers}
            </div>
        );
    }
}

数据库连接代码

public List<Customers> GetAllCustomers()
{
    List<Customers> customers = new List<Customers>();

    using (NpgsqlConnection connection = OpenConnection())
    {
        string query = "SELECT * FROM customers";
        NpgsqlCommand command = new NpgsqlCommand(query, connection);

        using (NpgsqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                customers.Add(new Customers
                {
                    Id = reader.GetInt32(0),
                    First_name = reader.GetString(1),
                    Last_name = reader.GetString(2),
                    Address = reader.GetString(3),
                    Zip = reader.GetString(4),
                    Phone = reader.GetString(5),
                    Email = reader.GetString(6),
                    Is_active = reader.GetBoolean(7)
                });
            }
        }
    }

    return customers;
}

排查步骤与解决方案

1. 检查后端路由注册

  • 确保Program.cs(或Startup.cs)中已启用控制器路由:
    app.MapControllers(); // 必须添加该代码,否则控制器路由不生效
    
  • 控制器的[Route("[controller]")]属性会生成/customers路由,确认该路由规则未被其他配置覆盖。

2. 直接验证API端点

  • 在浏览器或Postman中访问http://localhost:<后端端口>/customers:
    • 若返回404,说明后端路由未正确配置;
    • 若返回JSON数据,问题出在前端请求路径。

3. 修正前端请求路径

  • 相对路径fetch('customers')会基于当前页面URL拼接,若React页面URL为http://localhost:3000/customers,请求会变成http://localhost:3000/customers/customers,导致404。
  • 解决方式:
    • 使用绝对路径:fetch('http://localhost:<后端端口>/customers')(开发环境临时方案);
    • 配置代理:在React项目的package.json中添加"proxy": "http://localhost:<后端端口>",之后用fetch('/customers')即可自动转发请求到后端。

4. 配置CORS(跨域问题)

  • 若前后端运行在不同端口,需在ASP.NET Core中启用CORS:
    // Program.cs中
    builder.Services.AddCors(options =>
    {
        options.AddPolicy("AllowReact",
            policy => policy.WithOrigins("http://localhost:3000") // React项目端口
                            .AllowAnyHeader()
                            .AllowAnyMethod());
    });
    
    // 注意顺序:放在UseRouting之后,UseEndpoints之前
    app.UseCors("AllowReact");
    

5. 确认依赖注入配置

  • 检查DatabaseConnection是否已在Program.cs中注册为服务:
    builder.Services.AddScoped<DatabaseConnection>();
    
  • 若未注册,控制器构造函数无法获取实例,可能导致路由无法正常初始化。

6. 分析响应为HTML的原因

  • 404返回HTML通常是因为请求未匹配到API路由,ASP.NET Core返回了默认的错误页面。这说明请求路径或后端路由配置存在问题,需优先排查路由相关项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:35:28