Web Api 忽略路由属性
Posted
技术标签:
【中文标题】Web Api 忽略路由属性【英文标题】:Web Api Ignoring Route Attribute 【发布时间】:2021-11-26 21:16:14 【问题描述】:我正在处理一个 Web API 项目,当我运行它并尝试将路由用于控制器时,它不起作用,而是引发 404 错误。为什么 Web API 会忽略路由属性?
我将在下面留下代码:
[ApiController]
[Route("api/[controller]")]
public class Controller3 : ControllerBase
private readonly IServiceContract3 _interest;
public Controller3(IServiceContract3 interest)
_interest = interest;
[HttpGet]
[Route("[action]")]
[Route("api/Interest/GetInterests")]
public IEnumerable<Interest> GetEmployees()
return _interest.GetInterests();
[HttpPost]
[Route("[action]")]
[Route("api/Interest/AddInterest")]
public IActionResult AddInterest(Interest interest)
_interest.AddInterest(interest);
return Ok();
[HttpPost]
[Route("[action]")]
[Route("api/Interest/UpdateInterest")]
public IActionResult UpdateInterest(Interest interest)
_interest.UpdateInterest(interest);
return Ok();
[HttpDelete]
[Route("[action]")]
[Route("api/Interest/DeleteInterest")]
public IActionResult DeleteInterest(int id)
var existingInterest = _interest.GetInterest(id);
if (existingInterest != null)
_interest.DeleteInterest(existingInterest.Id);
return Ok();
return NotFound($"Employee Not Found with ID : existingInterest.Id");
[HttpGet]
[Route("GetInterest")]
public Interest GetInterest(int id)
return _interest.GetInterest(id);
对于我的 Startup.cs
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddControllers();
services.AddDbContextPool<DatabaseContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DB")));
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DatabaseContext context)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
context.Database.Migrate();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllers();
);
如何修复路由?每次我尝试在浏览器中执行此操作时,例如 https://localhost:44316/api/Interest/GetInterests,我都会收到 404 错误。为什么会这样?
【问题讨论】:
当你转到http
地址时会发生什么?
IServiceContract3
在哪里注册依赖注入?
【参考方案1】:
webapi 的控制器通常是这样定义的:
[ApiController]
[Route("api/[controller]")]
public sealed class InterestController : ControllerBase
private readonly IServiceContract3 _interest;
public InterestController(IServiceContract3 interest)
_interest = interest;
[HttpGet, Route("GetInterests")]
public IActionResult GetEmployees()
// this is located at: GET api/Interest/GetInterests
return Ok(_interest.GetInterests());
[HttpPost, Route("AddInterest")]
public IActionResult AddInterest([FromBody] Interest interest)
// this is located at: POST api/Interest/AddInterest
[HttpPost, Route("UpdateInterest")]
public IActionResult UpdateInterest([FromBody] Interest interest)
// this is located at: POST api/Interest/UpdateInterest
[HttpDelete, Route("DeleteInterest/id")]
public IActionResult DeleteInterest([FromRoute] int id)
// this is located at: DELETE api/Interest/DeleteInterest/id
[HttpGet, Route("GetInterest/id")]
public IActionResult GetInterest([FromRoute] int id)
// this is located at: GET api/Interest/GetInterest/id
return Ok(_interest.GetInterest(id));
首先,您要为控制器命名一个相关的名称,该名称将贯穿控制器的其余部分。所以,在这种情况下,我将Controller3
更改为InterestController
。由于控制器的路由是"/api/[Controller]"
,所以会转换成"api/Interest"
。
接下来,删除[Action]
属性。在这种情况下您不需要它们。
然后,确保您的路线正确。如果您要传递 ID,请使用 id
在路由中定义您的 ID,并设置 [FromRoute]
属性以清楚起见。此外,使用[FromBody]
定义将来自正文的参数。其中很多是“默认”的(意味着您不需要添加它们),但它有助于清晰。
最后,如果您使用IActionResult
模式,请通过您的控制器坚持使用它。不要跨端点混合/匹配返回类型,因为这会混淆维护。
最后一件事: 您的控制器端点名称有些多余。例如,您可以这样做:
[HttpGet, Route("")]
public IActionResult GetEmployees()
// this is located at: GET api/Interest
return Ok(_interest.GetInterests());
[HttpPut, Route("")]
public IActionResult AddInterest([FromBody] Interest interest)
// this is located at: PUT api/Interest/
[HttpPost, Route("")]
public IActionResult UpdateInterest([FromBody] Interest interest)
// this is located at: POST api/Interest/
[HttpDelete, Route("id")]
public IActionResult DeleteInterest([FromRoute] int id)
// this is located at: DELETE api/Interest/id
[HttpGet, Route("id")]
public IActionResult GetInterest([FromRoute] int id)
// this is located at: GET api/Interest/id
return Ok(_interest.GetInterest(id));
即:使用“HTTP 动词”来区分操作。
【讨论】:
【参考方案2】:您必须通过使 api 成为根来修复您的路线。将“api”替换为“~/api”。恕我直言,您应该从操作中删除 [action] 并将其添加到控制器中。同时修复控制器名称
[ApiController]
[Route("~/api/[controller]/[action]")]
public class InterestController : ControllerBase
[HttpGet("~/api/Interest/GetInterests")]
public IEnumerable<Interest> GetEmployees()
....
[HttpPost("~/api/Interest/AddInterest")]
public IActionResult AddInterest(Interest interest)
...
[HttpPost("~/api/Interest/UpdateInterest")]
public IActionResult UpdateInterest(Interest interest)
...
[HttpDelete("~/api/Interest/DeleteInterest/id")]
public IActionResult DeleteInterest(int id)
....
[HttpGet("~/api/Interest/GetInterest/id")]
public Interest GetInterest(int id)
【讨论】:
以上是关于Web Api 忽略路由属性的主要内容,如果未能解决你的问题,请参考以下文章