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
1 Answer
Reset to default 0I 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条)