ASP.Net Core WebApi中的非属性路由

时间:2017-12-19 02:27:20

标签: c# asp.net-web-api asp.net-core

我需要构建项目,实现供应商应用程序预定义的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 Core中,与旧的ASP.NET相比,构建REST-Api这样过于复杂的常见且重要的事情呢?

2 个答案:

答案 0 :(得分:2)

有一个nuget包SELECT COUNT(DISTINCT name) from users where users.age <= 42; ,主要目标是使从web api迁移到核心更容易。它还提供了一种方法来执行基于约定的路由到您需要的操作。所以,首先安装该软件包,然后在启动时:

Microsoft.AspNetCore.Mvc.WebApiCompatShim

在这个小配置之后,您可以从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}"); }); } 继承您的控制器,该控制器在上面的包中添加,以便于从web api或本机asp.net核心ApiController迁移。 Controller的示例:

ApiController

原生asp.net核心控制器:

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

您还可以使用以下属性标记基本控制器:

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

如果您不是从网络API迁移 - 我建议您使用原生[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 }); } } Controller具有不同的结构(类似于asp.net web api ApiController),因此没有太多理由将其用于除预期目标之外的任何其他内容(从web api迁移)。

答案 1 :(得分:1)

MapRoute仍然存在https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing

属性路由赞美MapRoute,而不是取代它。

显然,为了简化示例,有很多例子放弃了关于路由的部分。所以只需挖掘杓子。