简体   繁体   中英

Non-attribute routes in ASP.Net Core WebApi

I need to build project, that implement REST API predefined by vendor application(which will consume it) - there is about thousand of REST-resources with some actions defined by different HTTP-Verb's(POST, GET, PUT, DELETE, etc..).

So, ideally, for each resource i should have single class like this:

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)
  {
     // ...
  }
}

In previous versions i can just call MapHttpRoute while registering routes, inherit classes like this from ApiController - and ASP.NET Web Api will do as i need... But in .NET Core i can't find anything like MapHttpRoute/ApiController.. Now there is routing and http-verb attributes, and i need to define everything explicitly for each class/method:

[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)
    {
        // ...
    }
}

Writing this attributes for each of thousands REST-resources is very boring and error prone...

Do i miss something here? Why in pretty new and modern ASP.NET Core that very common and important thing as building REST-Api made so over-complicated, compared to old ASP.NET?

There is nuget package Microsoft.AspNetCore.Mvc.WebApiCompatShim which main goal is to make migration from web api to core easier. It also provides a way to perform convention-based routing to actions you need. So, first install that package, then in startup:

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

After this small configuration you can inherit your controllers either from ApiController , which is added in package above for convenience of migration from web api, or native asp.net core Controller . Example of 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 core 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 });
    }
}

You can also mark your base controller with these attributes:

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

If you are not migrating from web api - I'd suggest to use native Controller . ApiController has different structure (similar to asp.net web api ApiController), so there is not much reason to use it for anything other than its intended goal (migration from web api).

MapRoute is still there https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing

Attribute routing compliments MapRoute , not replaces it.

Apparently there are quite a few examples which drop the piece about Routing in order to simplify example. So just dig dipper.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM