5

Is it "legal" to have a controller inherit a route from its BaseController ? It seems it's not allowed for Attribute Routing , but how about normal route registration via RouteCollection?

The reason is I currently have a bunch of controllers, each representing some kind of file converter. Each of them has a common set of methods to upload the file to be converted. These method are endpoints on each controller not just private methods. I'd like for the following routes to be valid:

/api/controller1/uploadfile
/api/controller2/uploadfile
/api/controller3/uploadfile

Can I get an example how this could be done inside a BaseController and if it's not possible, an alternative.

2
  • 3
    Since Web API 2.2 it is possible to inherit route attributes. See asp.net/web-api/overview/releases/… Commented Nov 27, 2015 at 3:01
  • Thanks for the update! Commented Dec 1, 2015 at 21:27

3 Answers 3

2

Here's what works:

public abstract class BaseUploaderController : ApiController
{
    [HttpGet, Route("uploadfile")] //Needs both because HttpGet("uploadfile") currently only supported in MVC attribute routing 
    public string UploadFile() 
    {
        return "UploadFile";
    }
}


[RoutePrefix("api/values")]
public class ValuesController : BaseUploaderController
{
    [Route("{id:int}")]
    public string Get(int id)
    {
        return "value";
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

yeah that may very well be the case sorry. See if AttributeRouting provides a solution. attributerouting.net/#asp-net-mvc
I assume you set up the imperative routing? Those route attributes make it seem like you got attribute routing to work, which it doesn't work for me.
1

Are you looking to place this UploadFile action in the base controller and other controllers inheriting from them should still be able to hit UploadFile from their respective routes like you mentioned in your post? If yes, you could create an abstract base api controller and place this UploadFile action in it and your requests to the individual controllers should work as expected.

Example:

public abstract class BaseApiController : ApiController
{
    // POST /api/Values
    // POST /api/Test
    public string UploadFile()
    {
        return "UploadFile";
    }
}

public class TestController : BaseApiController
{
    // GET /api/test/10
    public string GetSingle(int id)
    {
        return "Test.GetSingle";
    }
}

public class ValuesController : BaseApiController
{
    // GET /api/values/10
    public string GetSingle(int id)
    {
        return "Values.GetSingle";
    }
}

4 Comments

Hey sorry this either doesn't work or my question was unclear. With the setup you have I want api/values/uploadfile and api/test/uploadfile to both be valid routes and hit UploadFile method. Currently it thinks "uploadfile" is an integer I'm passing to api/value/{int} route and that throws a conversion error. I need it to hit the base class instead
ok..i just was trying to give an example...but let's say if you have a route like api/{controller}/{id}, id = RouteParameter.Optional, then a request like POST /api/test/uploadfile would indeed hit the base UploadFile method...could you share how your routes are setup?
Thank you for the example. That's the route I have and it doesnt work. Gives the error I described in the comment. I used your example in a brand new project
I concur, using a base class doesn't work. I don't think there's a way to use a base class. Which sucks.
1

As per this answer https://stackoverflow.com/a/21610390/122507 attribute routes are not inherited.

I am currently debating between introducing unnecessary method in 30 controllers just so I can add an attribute route or add a fake parameter to the base class method to let the default routing disambiguate between Get(int id) and GetHistory(int id, bool history) where I don't need the second parameter.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.