如何使用 ApiController 修复路由失败?

How to fix routing failure with ApiController?

我有一个名为“OdeToFood”的小型 ASP.NET 核心网络应用程序项目。开发环境包括:

  1. IDE:Visual Studio 2019 年 Windows 10 台电脑
  2. ASP.NET 核心 3.1
  3. 使用 Dapper 从 SQL 数据库访问数据
  4. 不使用 MVC

在其中一个网页中,jQuery .ajax 将用于从数据库中检索记录。我添加了一个类型为“API 具有 read/write 操作的控制器”的 ApiController,因为该项目中未使用 EF。

这是 VS 自动生成的代码(没有做任何更改)。

namespace OdeToFood.Api
{
    [Route("api/[controller]")]
    [ApiController]
    public class RestaurantsController : ControllerBase
    {
        // GET: api/<RestaurantsController>
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/<RestaurantsController>/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/<RestaurantsController>
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api/<RestaurantsController>/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/<RestaurantsController>/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

我尝试使用以下 URL 从浏览器对其进行测试:

  1. https://localhost:44361/api/Restaurants
  2. https://localhost:44361/api/Restaurants/8
  3. https://localhost:44361/api/Restaurants控制器
  4. https://localhost:44361/api/RestaurantsController/8

他们都因 HTTP 404 错误而失败。

由于上面的代码已经在 [Route ...] 中使用了“属性路由”,我认为前 2 个 URL int test 应该可以工作。但他们没有。我不明白为什么。任何帮助或建议将不胜感激。

在 startup.cs 文件中,配置部分具有以下设置:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

在 startup.cs

中尝试以下操作
 app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });

在下方评论;

endpoints.MapRazorPages();

Your Scenario:

Though the solution is very straight forward, I felt more explanation for you to get rid of any further confustions.

正如您所说 "Visual Studio 2019" 因此,如果您选择了 asp.net core web api 项目,它将使用 weather forecast api controller 创建,默认为 startup.cs ,如下所示:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

因此,如果您直接 运行 项目,它应该 运行 和 default action 如下所示:

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }

So now come to your projects configuration which is containing like below:

app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });

Means its looking for simple mvc razor page and when you are trying to hit either of this URLs 1. https://localhost:44361/api/Restaurants or 2.https://localhost:44361/api/Restaurants/8 it should get 404 because it's not routed accordingly. So your routing template is not correct to route api controller directly. endpoints.MapRazorPages() is usually used for Razor mvc page routing.

Solution:

如果您可以在服用 RestaurantsController 时添加 API controller,我认为它看起来会像您发布的那样。 如果您替换下面的 service

并且请求应该按预期路由
       app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

Note: You even can override your route template if you want. You could have a look here also if you want which a conventional route.

Output:

我试图向您展示的是什么误导了您并使您的想法更加清晰。如果您有任何进一步的疑问,请查看我们的 official document here。希望对您有所帮助。