简体   繁体   English

Web Api 忽略路由属性

[英]Web Api Ignoring Route Attribute

I am working on a Web API project and when I run it and try to use the route for a controller, it doesn't work and instead, it throws me a 404 error.我正在研究 Web API 项目,当我运行它并尝试使用 controller 的路线时,它不起作用,而是抛出了一个错误。 Why is the Web API ignoring the route attribute?为什么 Web API 忽略了路由属性?

I'll leave the code below:我将在下面留下代码:

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

}

And for my Startup.cs对于我的 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();
        });
    }
}

How can I fix the routing?如何修复路由? Every time I try to do it in my browser like https://localhost:44316/api/Interest/GetInterests I get a 404 error instead.每次我尝试在 https://localhost:44316/api/Interest/GetInterests 之类的浏览器中执行此操作时,我都会收到 404 错误。 Why is this happening?为什么会这样?

you have to fix your route by making api a root.您必须通过使 api 成为根来修复您的路线。 Replace "api" by "~/api".将“api”替换为“~/api”。 IMHO you should remove [action] from actions and add it to a controller.恕我直言,您应该从操作中删除 [action] 并将其添加到 controller。 Also fix a controller name还修复了 controller 名称

    [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)

Typically controllers for a webapi are defined as so:通常,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));
    }
}

First, you want to name your controller a relevant name that will carry throughout the rest of your controller.首先,您要将 controller 命名为一个相关名称,该名称将贯穿您的 controller 的整个 rest。 So, this this case, I changed Controller3 to InterestController .因此,在这种情况下,我将Controller3更改为InterestController Since the route of the controller is "/api/[Controller]" , it will translate to "api/Interest" .由于 controller 的路由是"/api/[Controller]" ,它会翻译成"api/Interest"

Next, remove the [Action] attributes.接下来,删除[Action]属性。 You do not need them in this scenario.在这种情况下,您不需要它们。

Then, make sure your routes are correct.然后,确保您的路线是正确的。 If you are passing an ID, define your ID in the route using {id} and setting the [FromRoute] attribute for clarity.如果您传递一个 ID,请使用{id}在路由中定义您的 ID,并设置[FromRoute]属性以清楚起见。 Also, use [FromBody] to define parameters that will be coming from the body.此外,使用[FromBody]定义将来自正文的参数。 A lot of these are "default" (meaning you don't need to add them), but it helps with clarity.其中很多是“默认”的(意味着您不需要添加它们),但它有助于清晰。

Finally, if you are using the IActionResult pattern, then stick with that through your controller.最后,如果您使用的是IActionResult模式,请通过 controller 坚持下去。 Don't mix/match return types across endpoints because it's confusing for maintenance.不要跨端点混合/匹配返回类型,因为这会混淆维护。

One final thing: Your controller endpoint names are slightly redundant.最后一件事:您的 controller 端点名称有点多余。 For example, you could do this:例如,您可以这样做:

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

ie: Use the "HTTP Verb" to your advantage to segregate actions.即:使用“HTTP 动词”来区分操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM