How do I set up RESTful attribute routing in ASP.Net Core API if using Namespace version routing

639 views Asked by At

I am building an ASP.Net Core 1.1.0 web API.

As a supporting comment, I have chosen to use Peter Lazzarino's versionrouting NuGet package to allow me to separate my controllers into different namespaces (and folders) based on version. I configured this in my Startup.cs as recommended by Peter and it builds without errors. I am using

var apiPrefix = "api";  

in Startup.cs to allow all of my routes to start with api, as per Peter's recommendation.

I want to follow RESTful guidelines and utilize HTTP verb attributes for my methods.

I want my clients to be able to go to http://companyname.com/api/v1/mycontroller/status and since I have MyController located in the the folder "Controllers\v1\MyController.cs" in my API project, the versionrouting library should be able to find it.

Within my controller, I have the following;

namespace MyProject.Controllers.v1
{
    public class MyController : Controller
    {

        // GET: ~/api/v1/mycontroller/status
        [HttpGet("/status")]
        public JsonResult Status()
        {
            return Json(new { status = "API is running" });
        }

    }
}

However, navigating to http://companyname.com/api/v1/mycontroller/status gives me a 404 error.

I had tried to leave this question as a comment in the SO post How can versioning be done in ASP.NET Core Web Api , but I do not have a high enough reputation yet in StackOverflow to leave a comment. :(

So, hopefully someone here can help me out.

Thanks in advance for any help you can offer.

4

There are 4 answers

1
Kos On

You can simply decorate your controller with:

[Route("api/v1/[controller]/[action]")]
public class MyController : Controller
{

    // GET: ~/api/v1/mycontroller/status
    [HttpGet]
    public JsonResult Status()
    {
        return Json(new { status = "API is running" });
    }

}

Then your route will be:

http://companyname.com/api/v1/mycontroller/status 
0
EiEiGuy On

The solution to my problem required that I do not use any Route attribute for the class (since the namespaceversioning NuGet code is building essentially a MapRoute for api/v1/mycontroller) and also not to use the forward slash in front of the HttpGet action attribute property (i.e. [HttpGet("Status")] instead of [HttpGet("/Status")] ). Once I made that change, it started working as expected.

0
Fabien Mwamba On

you can use Routes Attributes on the controller as specified in the asp.net core documentation that way you can have versioning of your api but then you will have to add it to every controller to keep your code in sync, i do not know exactly where you can add it globally. Hope this helps

0
Chris Martinez On

This particular feature wasn't supported at the time, API Versioning now supports achieving this particular setup out-of-the-box using API Version Conventions.

You need only configure your application and apply the route constraint in your templates.

services.AddApiVersioning(options =>
    options.Conventions.Add( new VersionByNamespaceConvention() );

Your service now only need be defined as:

[ApiVersion("1.0")]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
public class MyController : ControllerBase
{
    // GET: ~/api/v1/my/status
    [HttpGet]
    public IActionResult Status()
    {
        return Ok(new { status = "API is running" });
    }
}