c# - React + ASP.NET Core project template can't hit new controller endpoint from client - Stack Overflow

I'm using the built in project template for React and ASP.NET Core from Visual Studio 2022 which c

I'm using the built in project template for React and ASP.NET Core from Visual Studio 2022 which creates a React client application and a ASP.NET Core backend server application.

I wanted to test adding a new controller besides the default weather forecast controller and hitting that endpoint using the useEffect hook in the app.jsx file. When I add an async function to target the endpoint "Test", the endpoint in my new controller never gets hit. I've tried to structure the controller the same as the weather forecast controller, but the new controller never gets triggered from the client. I can hit the endpoint using swagger. I feel like there is a simple solution to this problem, some kind of controller registration that I'm missing, but I can't find it.

This is my app.jsx file. I added a useState hook to set and get testMessage constant, and an async method populateTestData to fetch data from the 'Test' controller Get endpoint to set testMessage.

import { useEffect, useState } from 'react';
import './App.css';

function App() {
    const [forecasts, setForecasts] = useState();
    const [testMessage, setTestMessage] = useState();

    useEffect(() => {
        populateWeatherData();
        populateTestData();
    }, []);

    const contents = forecasts === undefined
        ? <p><em>Loading... Please refresh once the ASP.NET backend has started. See <a href=";>;/a> for more details.</em></p>
        : <table className="table table-striped" aria-labelledby="tableLabel">
            <thead>
                <tr>
                    <th>Date</th>
                    <th>Temp. (C)</th>
                    <th>Temp. (F)</th>
                    <th>Summary</th>
                </tr>
            </thead>
            <tbody>
                {forecasts.map(forecast =>
                    <tr key={forecast.date}>
                        <td>{forecast.date}</td>
                        <td>{forecast.temperatureC}</td>
                        <td>{forecast.temperatureF}</td>
                        <td>{forecast.summary}</td>
                    </tr>
                )}
            </tbody>
        </table>;

    const message = testMessage === undefined ? <p><em>Loading from Server...</em></p> : <h3>{testMessage}</h3>;
    return (
        <div>
            <h1 id="tableLabel">Weather forecast</h1>
            <p>This component demonstrates fetching data from the server.</p>
            {contents}
            {message}
        </div>
    );
    
    async function populateWeatherData() {
        const response = await fetch('weatherforecast');
        const data = await response.json();
        setForecasts(data);
    }

    async function populateTestData() {
        const response = await fetch('test');
        const data = await response.json();
        setTestMessage(data);
    }
}

export default App;

This is my TestController. I tried to structure this similar to the default WeatherForecastController. The populateTestData function should hit the Get() endpoint in this controller, but my breakpoint at that method call never gets hit

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ReactDotNetPractice.Server.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        private readonly ILogger<TestController> _logger;

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

        [HttpGet(Name = "GetTest")]
        public string Get()
        {
            return "This is the test message you should receive from the Test endpoint.";
        }
    }
}

WeatherForecastController - mostly including this for reference. The Get endpoint in this controller is hit by the populateWeatherData method in app.jsx every time the page loads, like it should:

using Microsoft.AspNetCore.Mvc;

namespace ReactDotNetPractice.Server.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(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

Program.cs file, in case that's helpful, though I don't see anywhere that is configuring the WeatherForecastController specifically

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at 
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

app.UseDefaultFiles();
app.UseStaticFiles();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.MapFallbackToFile("/index.html");

app.Run();

I'm using the built in project template for React and ASP.NET Core from Visual Studio 2022 which creates a React client application and a ASP.NET Core backend server application.

I wanted to test adding a new controller besides the default weather forecast controller and hitting that endpoint using the useEffect hook in the app.jsx file. When I add an async function to target the endpoint "Test", the endpoint in my new controller never gets hit. I've tried to structure the controller the same as the weather forecast controller, but the new controller never gets triggered from the client. I can hit the endpoint using swagger. I feel like there is a simple solution to this problem, some kind of controller registration that I'm missing, but I can't find it.

This is my app.jsx file. I added a useState hook to set and get testMessage constant, and an async method populateTestData to fetch data from the 'Test' controller Get endpoint to set testMessage.

import { useEffect, useState } from 'react';
import './App.css';

function App() {
    const [forecasts, setForecasts] = useState();
    const [testMessage, setTestMessage] = useState();

    useEffect(() => {
        populateWeatherData();
        populateTestData();
    }, []);

    const contents = forecasts === undefined
        ? <p><em>Loading... Please refresh once the ASP.NET backend has started. See <a href="https://aka.ms/jspsintegrationreact">https://aka.ms/jspsintegrationreact</a> for more details.</em></p>
        : <table className="table table-striped" aria-labelledby="tableLabel">
            <thead>
                <tr>
                    <th>Date</th>
                    <th>Temp. (C)</th>
                    <th>Temp. (F)</th>
                    <th>Summary</th>
                </tr>
            </thead>
            <tbody>
                {forecasts.map(forecast =>
                    <tr key={forecast.date}>
                        <td>{forecast.date}</td>
                        <td>{forecast.temperatureC}</td>
                        <td>{forecast.temperatureF}</td>
                        <td>{forecast.summary}</td>
                    </tr>
                )}
            </tbody>
        </table>;

    const message = testMessage === undefined ? <p><em>Loading from Server...</em></p> : <h3>{testMessage}</h3>;
    return (
        <div>
            <h1 id="tableLabel">Weather forecast</h1>
            <p>This component demonstrates fetching data from the server.</p>
            {contents}
            {message}
        </div>
    );
    
    async function populateWeatherData() {
        const response = await fetch('weatherforecast');
        const data = await response.json();
        setForecasts(data);
    }

    async function populateTestData() {
        const response = await fetch('test');
        const data = await response.json();
        setTestMessage(data);
    }
}

export default App;

This is my TestController. I tried to structure this similar to the default WeatherForecastController. The populateTestData function should hit the Get() endpoint in this controller, but my breakpoint at that method call never gets hit

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ReactDotNetPractice.Server.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        private readonly ILogger<TestController> _logger;

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

        [HttpGet(Name = "GetTest")]
        public string Get()
        {
            return "This is the test message you should receive from the Test endpoint.";
        }
    }
}

WeatherForecastController - mostly including this for reference. The Get endpoint in this controller is hit by the populateWeatherData method in app.jsx every time the page loads, like it should:

using Microsoft.AspNetCore.Mvc;

namespace ReactDotNetPractice.Server.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(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

Program.cs file, in case that's helpful, though I don't see anywhere that is configuring the WeatherForecastController specifically

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

app.UseDefaultFiles();
app.UseStaticFiles();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.MapFallbackToFile("/index.html");

app.Run();
Share Improve this question edited Nov 16, 2024 at 15:36 marc_s 757k184 gold badges1.4k silver badges1.5k bronze badges asked Nov 16, 2024 at 15:17 Jon SowersJon Sowers 253 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I found the solution to this, it was in the vite.config.js file in the React Client application. There is a section that will allow you to set proxy addresses for server calls, weatherforecast was set there but test was not. This is the corrected vite.config.js file

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [plugin()],
    resolve: {
        alias: {
            '@': fileURLToPath(new URL('./src', import.meta.url))
        }
    },
    server: {
        proxy: {
            '^/weatherforecast': {
                target,
                secure: false
            },
            '^/test': {
                target,
                secure: false
            }
        },
        port: 5173,
        https: {
            key: fs.readFileSync(keyFilePath),
            cert: fs.readFileSync(certFilePath),
        }
    }
})

vite config documentation: https://vitejs.dev/config/

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745655080a4638494.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信