【问题标题】:How to fix routing failure with ApiController?如何使用 ApiController 修复路由失败?
【发布时间】:2023-03-17 05:14:02
【问题描述】:

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

  1. IDE:Windows 10 PC 上的 Visual Studio 2019
  2. ASP.NET Core 3.1
  3. 使用 Dapper 从 SQL DB 访问数据
  4. 不使用 MVC

在其中一个网页中,将使用 jQuery .ajax 从 DB 中检索记录。我添加了一个类型为“具有读/写操作的 API 控制器”的 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/RestaurantsController
  4. https://localhost:44361/api/RestaurantsController/8

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

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

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

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();
    });
}

【问题讨论】:

    标签: c# asp.net-core url-routing asp.net-apicontroller


    【解决方案1】:

    在您的 startup.cs 中尝试以下操作

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

    在下方评论;

    endpoints.MapRazorPages();
    

    【讨论】:

      【解决方案2】:

      Your Scenario:

      虽然解决方案很简单,但我觉得解释得更多 让您摆脱任何进一步的困惑。

      正如你所说的"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();
              }
      

      所以现在来到你的项目configuration,其中包含类似 下面:

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

      表示它正在寻找simple mvc razor page 以及当您尝试时 要点击URLs 1. https://localhost:44361/api/Restaurants or 2.https://localhost:44361/api/Restaurants/8 中的任何一个,它应该得到404,因为它没有相应地路由。因此,您的 routing template 直接与 route api controller 不正确。 endpoints.MapRazorPages() 通常用于Razor mvc page routing

      Solution:

      如果您在使用RestaurantsController 时可以添加API controller,我想它会像您发布的那样。 如果您替换下面的service

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

      Note: 如果需要,您甚至可以override 您的路线模板。如果你想要哪个,你也可以have a look here conventional route.

      Output:

      我尝试向您展示的是什么会误导您并强化您的想法。如果您有任何进一步的疑问,请查看我们的official document here。希望对您有所帮助。

      【讨论】:

      • 因为该项目同时使用 Razor 页面和 ApiController,所以我按照您的解决方案添加了 endpoint.MapController 并保留了 endpoint.MapRazorPages 设置。它对双方都有效。如果我有很多地方使用 .ajax 和 jQuery,我应该在解决方案中添加一个 WebApi 项目吗?现在,WebApi 项目是否正在取代 ApiController?
      • 感谢您提供的解决方案。我对在发布的 cmets 中是否使用 ApiController 或 WebApi 项目有疑问。你能给我一些建议吗?谢谢。
      • 感谢您的反馈,好吧,如果您的client side 项目和backend 项目在不同的地方,最好有WebApi,另一方面它会很容易维护,如果您的client side 项目和backend 在同一个项目中,它们紧密耦合,将来处理跨平台请求的可能性较小,那么您可以使用API controller 而不是拥有WEB API 项目本身。重要的是 WEB API 专为处理大数据驱动请求、跨平台请求而设计,您将在其中处理 Json data
      • 您可以在您的MVC 项目中使用API Controller 来处理这种data driven request,在这种情况下您必须定义您的路线。管理在MVC 项目上添加API Controller 的小型请求也会很好。但是如果您的项目基本上是为处理大规模数据而设计的,那么WEB API 绝对是一个不错的选择。希望你得到正确的解释。如果您有任何其他问题,请随时告诉我。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 2017-11-10
      相关资源
      最近更新 更多