ASP.NET Core Web API:按方法名称路由?

ASP.NET Core Web API: Routing by method name?

我记得在 ASP.NET Web API 中,在 Web API REST 方法名称前面加上 HTTP 命令就足够了(例如 GetList() => HTTP GET , Delete() => HTTP DELETE) 以适当路由来电。

我还记得在 ASP.NET Web API 中会进行参数匹配,因此即使 Get(int id)Get(int id, string name) 也可以自动且适当地进行路由而无需任何属性。

public class MyController
{
  public ActionResult Get(int id) => ...

  public ActionResult Get(int id, string name) => ...

  public ActionResult DeleteItem(int id) => ...
}

这不是在 ASP.NET Web API Core 中可用吗?

这适用于 Core 2 是的,但我知道如何做到这一点的方式是这样的

[Route("api/[controller]")]
[ApiController]
public class AvailableRoomsController : ControllerBase
{
    private readonly ApplicationContext _context;

    public AvailableRoomsController(ApplicationContext context)
    {
        _context = context;
    }

    // GET: api/AvailableRooms
    [HttpGet]
    public async Task<ActionResult<IEnumerable<AvailableRoom>>> GetAvailableRooms()
    {
        return await _context.AvailableRooms.ToListAsync();
    }


    // POST: api/AvailableRooms
    [HttpPost]
    public async Task<ActionResult<AvailableRoom>> PostAvailableRoom(AvailableRoom availableRoom)
    {
        _context.AvailableRooms.Add(availableRoom);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetAvailableRoom", new { id = availableRoom.Id }, availableRoom);
    }

    [HttpPut] .... etc
}

现在,根据您指定的 REST 操作类型以及您发送给 "api/AvailableRooms" 的模型类型,如果存在适当的操作,将选择它。

Visual Studio 2019 和我认为 2017 可以自动创建这样的控制器,如果您右键单击您的控制器文件夹并单击添加->控制器,然后选择 "API Controller with actions, using Entity Framework" 并选择您的模型之一类.

你只需要将路由添加到控制器的顶部。

指定路由api,控制器和动作:

[Route("api/[controller]/[action]")]
[ApiController]
public class AvailableRoomsController : ControllerBase
{
...
}

我们既不能做动作重载也不能前缀动作名称作为 Http verb.The 路由在 ASP.NET 中的工作方式与在 ASP.NET Web Api 中的工作方式不同.

但是,您可以简单地组合这些操作,然后在内部分支,因为如果您作为查询字符串发送,所有参数都是可选的

[HttpGet]
public ActionResult<string> Get(int id, string name)
{
  if(name == null){..}
  else{...}
}

或者你需要使用属性路由来指定每个api 如果你发送路由数据:

[HttpGet("{id}")]       
public ActionResult<string> Get(int id)
{
    return "value";
}


[HttpGet("{id}/{name}")]
public ActionResult<string> Get(int id, string name)
{
    return name;
}

参考Attribute Routing,

aspnetcore webapi 控制器本身不支持通过命名约定推断 http 动词,但允许您创建自己的约定并实现此行为。

创建您的约定

public class MyConvention : IApplicationModelConvention
{
    public void Apply(ApplicationModel application)
    {
        foreach(var controller in application.Controllers)
        {
            foreach(var action in controller.Actions)
            {
                if (action.ActionName.StartsWith("Post"))
                {
                    action.Selectors.First().ActionConstraints.Add(new HttpMethodActionConstraint(new[]{ "POST" }));
                }
            }
        }
    }
}

然后在Program/Startup中注册:

builder.Services.AddControllers(configure => configure.Conventions.Insert(0, new MyConvention()));