我需要构建项目,实现由供应商应用程序(将使用它)预定义的 REST API - 大约有数千个 REST 资源,其中一些操作由不同的 HTTP-Verb(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-verb 属性,我需要为每个类/方法明确定义所有内容:
[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 相比,为什么在相当新的和现代的 ASP.NET Core 中,构建 REST-Api 这样非常常见和重要的事情变得如此复杂?
请您参考如下方法:
有 nuget 包 Microsoft.AspNetCore.Mvc.WebApiCompatShim 其主要目标是使从 web 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 继承你的 Controller ,它被添加到上面的包中以方便从 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);
}
}
native asp.net 核心 Controller :
// 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 });
}
}
您还可以使用这些属性标记您的基本 Controller :
[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 迁移 - 我建议使用 native Controller。 ApiController 具有不同的结构(类似于 asp.net web api ApiController),因此没有太多理由将其用于预期目标(从 web api 迁移)以外的任何用途。
