英文:
Correct MVC path mapping .NET 6 using React
问题
I suspect this is a very simple solution. I have created a brand new ASP.NET Core 6 project (in VS 2022) with React. The default project has a WeatherForecast component. I have duplicated this component and attempted to create a new controller. Unfortunately it is only returning the fallback Index.html.
Here is the code:
// React
async getSitemapData() {
    //axios.get("Sitemap")
    //    .then(resp => {
    //        console.log(resp.data);
    //        this.setState({ sitemap: resp.data, loading: false });
    //    });
    const response = await fetch('sitemap');
    const data = await response.json(); //execution does not reach this line
    console.log(data);
    this.setState({ sitemap: data, loading: false });
}
//program.cs controller mapping
app.UseStaticFiles();
app.UseRouting();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");
app.MapFallbackToFile("index.html"); 
//SitemapController.cs
using Microsoft.AspNetCore.Mvc;
namespace Intranet.Controllers
{
    [ApiController]
    [Route("[controller]")]
    //public class DataController : ControllerBase
    //Edit updated controller name
    public class SitemapController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            try
            {
                // Read the data.json file and return its contents as JSON
                var path = Path.Combine(Directory.GetCurrentDirectory(), "/App_Data/sitemap.json");
                var data = System.IO.File.ReadAllText(path);
                return new JsonResult(data);
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
            }
        }
    }
}
And for reference here is the functioning WeatherForecastController:
//WeatherForecastController.cs
using Microsoft.AspNetCore.Mvc;
namespace Intranet.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        [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();
        }
    }
}
Aside from the returned datatype (the sitemap reads a JSON file and returns the contents rather than an array. The JSON is valid as I have used it in another site which is being revamped now), everything I can see tells me it should work. Thank you.
英文:
I suspect this is a very simple solution. I have created a brand new ASP.NET Core 6 project (in VS 2022) with React. The default project has a WeatherForecast component. I have duplicated this component and attempted to create a new controller. Unfortunately it is only returning the fallback Index.html.
Here is the code:
// React
async getSitemapData() {
        //axios.get("Sitemap")
        //    .then(resp => {
        //        console.log(resp.data);
        //        this.setState({ sitemap: resp.data, loading: false });
        //    });
        const response = await fetch('sitemap');
        const data = await response.json(); //execution does not reach this line
        console.log(data);
        this.setState({ sitemap: data, loading: false });
}
//program.cs controller mapping
app.UseStaticFiles();
app.UseRouting();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");
app.MapFallbackToFile("index.html"); 
//SitemapController.cs
using Microsoft.AspNetCore.Mvc;
namespace Intranet.Controllers
{
    [ApiController]
    [Route("[controller]")]
    //public class DataController : ControllerBase
//Edit updated controller name
    public class SitemapController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            try
            {
                // Read the data.json file and return its contents as JSON
                var path = Path.Combine(Directory.GetCurrentDirectory(), "/App_Data/sitemap.json");
                var data = System.IO.File.ReadAllText(path);
                return new JsonResult(data);
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
            }
        }
    }
}
And for reference here is the functioning WeatherForecastController:
//WeatherForecastController.cs
using Microsoft.AspNetCore.Mvc;
namespace Intranet.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        [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();
        }
    }
}
Aside from the returned datatype (the sitemap reads a JSON file and returns the contents rather than an array. The JSON is valid as I have used it in another site which is being revamped now), everything I can see tells me it should work. Thank you.
答案1
得分: 0
Most likely, your code is not finding the JSON file you're trying to read. A likely culprit is Directory.GetCurrentDirectory which might not be what you expect at runtime.
For serving static files, the ASP.NET documentation has the following suggestion:
Consider a directory hierarchy in which the static files to be served reside outside of the web
- wwwroot
- css
 - images
 - js
 
 - MyStaticFiles
- images
- red-rose.jpg
 
 
 - images
 
A request can access the red-rose.jpg file by configuring the Static File Middleware as follows:
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
           Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
    RequestPath = "/StaticFiles"
});
In the preceding code, the MyStaticFiles directory hierarchy is exposed publicly via the StaticFiles URI segment. A request to https://
英文:
Most likely, your code is not finding the JSON file you're trying read. A likely culprit Directory.GetCurrentDirectory which might not be what you expect at runtime.
For serving static files, the ASP.NET documentation has the following suggestion:
> Consider a directory hierarchy in which the static files to be served
> reside outside of the web
>
> - wwwroot
>   - css
>   - images
>   - js
> - MyStaticFiles
>   - images
>     - red-rose.jpg
>
> A request can access the red-rose.jpg file by configuring the Static
> File Middleware as follows:
>
>     // Code omitted for brevity
>  
>     app.UseStaticFiles(new StaticFileOptions
>     {
>         FileProvider = new PhysicalFileProvider(
>                Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
>         RequestPath = "/StaticFiles"
>     });
>
>     // Code omitted for brevity
>
> In the preceding code, the MyStaticFiles directory hierarchy is
> exposed publicly via the StaticFiles URI segment. A request to
> https://<hostname>/StaticFiles/images/red-rose.jpg serves the
> red-rose.jpg file.
答案2
得分: 0
你需要首先将URL添加到 setupProxy.js 文件中:
const context = [
    "/weatherforecast",
    
     // 在这里添加
    "/sitemap"
];
然后,你可以使用以下代码来访问 SitemapController 终端:
const response = await fetch('sitemap');
英文:
You need to add the URL into setupProxy.js firstly
const context = [
    "/weatherforecast",
     //add here 
    "/sitemap"
];
Then you can use const response = await fetch('sitemap'); to hit the SitemapController endpoint.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论