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;
}
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()));
我记得在 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;
}
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()));