【问题标题】:Web Api Ignoring Route AttributeWeb Api 忽略路由属性
【发布时间】: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 在哪里注册依赖注入?

标签: c# api web webapi


【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 2017-08-16
      相关资源
      最近更新 更多