Неатрибутивные маршруты в ASP.Net Core WebApi
Мне нужно построить проект, который реализует REST API, предопределенный приложением поставщика (которое будет его использовать) - существует около тысячи REST-ресурсов с некоторыми действиями, определенными различными HTTP-глаголами (POST, GET, PUT, DELETE и т. Д.).).
Итак, в идеале, для каждого ресурса у меня должен быть один класс:
public class SomethingController
{
public Something Post(string name, DateTime time)
{
// ...
}
public int PostStrange(string text)
{
// ...
}
public Something Put([FromBody]Something item)
{
// ...
}
public void Delete(int id)
{
// ...
}
}
В предыдущих версиях я мог просто вызывать MapHttpRoute при регистрации маршрутов, наследовать классы, как это от ApiController
- и ASP.NET Web Api будет делать так, как мне нужно... Но в.NET Core я не могу найти ничего подобного MapHttpRoute/ApiController.. Теперь есть атрибуты маршрутизации и http-глагола, и мне нужно явно определить все для каждый класс / метод:
[Route("api/[controller]")]
public class SomethingController : Controller
{
[HttpPost]
public Something Post(string name, DateTime time)
{
// ...
}
[HttpPost("api/[controller]/strange")]
public int PostStrange(string text)
{
// ...
}
[HttpPut]
public Something Put([FromBody]Something item)
{
// ...
}
[HttpDelete]
public void Delete(int id)
{
// ...
}
}
Запись этих атрибутов для каждого из тысяч REST-ресурсов очень скучна и подвержена ошибкам...
Я что-то здесь скучаю? Почему в довольно новом и современном ASP.NET Core такая распространенная и важная вещь, как сборка REST-Api, стала слишком сложной по сравнению со старым ASP.NET?
2 ответа
Есть пакет nuget Microsoft.AspNetCore.Mvc.WebApiCompatShim
основная цель которого - облегчить переход с веб-API на ядро. Он также предоставляет способ выполнения конвенциональной маршрутизации к нужным вам действиям. Итак, сначала установите этот пакет, затем при запуске:
public void ConfigureServices(IServiceCollection services) {
// add conventions here
services.AddMvc().AddWebApiConventions();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.UseMvc(routes => {
// map one global route
routes.MapWebApiRoute("WebApi", "api/{controller}");
});
}
После этой небольшой конфигурации вы можете наследовать ваши контроллеры либо от ApiController
, который добавлен в пакет выше для удобства миграции с web api или нативного ядра asp.net Controller
, Пример ApiController
:
public class SomeController : ApiController {
// maps to GET /api/Some
// note - no routing attributes anywhere
public HttpResponseMessage Get() {
return new HttpResponseMessage(HttpStatusCode.OK);
}
// maps to POST /api/Some
public HttpResponseMessage Post() {
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
Родной контроллер ядра asp.net:
// mark with these attributes for it to work
[UseWebApiRoutes]
[UseWebApiActionConventions]
public class TestController : Controller {
// maps to GET /api/Test
// no routing attributes, but two "conventions" attributes
public IActionResult Get(string p) {
return new ObjectResult(new { Test = p });
}
}
Вы также можете пометить свой базовый контроллер следующими атрибутами:
[UseWebApiRoutes]
[UseWebApiActionConventions]
public class BaseController : Controller {
}
public class TestController : BaseController {
// maps to GET /api/Test
// no attributes
public IActionResult Get(string p) {
return new ObjectResult(new { Test = p });
}
}
Если вы не переходите с веб-API - я бы предложил использовать нативный Controller
, ApiController
имеет другую структуру (аналогичную веб-интерфейсу asp.net ApiController), поэтому нет особых оснований использовать его для чего-либо, кроме своей цели (миграция из веб-интерфейса API).
MapRoute
все еще там https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing
Атрибут маршрутизации MapRoute
не заменяет.
По-видимому, есть довольно много примеров, которые опускают часть о маршрутизации, чтобы упростить пример. Так что просто копай ковшом.