1
votes

When using web api, how does one call the proper routing methods if you use [RoutePrefix()]

Say you have something like "MyReallyLongNamedClassController". the default route would be http:...com/api/MyReallyLongNamedClass. The application then goes by methods named Get, Post, Put, etc (unless of course using verb decorators).

If I put a route prefix decorator of [RoutePrefix("api/LongClass")] on my controller, how can I have web api still use the defaults for the methods?

Meaning, I want the method named "GetAll()" to still map to "api/LongClass" (when using a get header) and "PostThis(int id)" to still map to "api/LongClass/{id}" (when using a post header)

3

3 Answers

5
votes

Here's what I did to solve the problem without having to decorate all methods with annotations. I put RoutePrefix at the class level, as well as the default Route

[RoutePrefix("api/longclass")]
[Route("{id?}")]
public class MyReallyLongNamedClass: ApiController
{

    public string GetAll(int id)
    { 
        return "result";
    }


    public string PostThis([FromBody] MyModel model)
    {
       var res=  _repository.Save(model);
       return res;
    }
}
1
votes

Another option: if all you want to do is change the controller name in the route, you can create a custom controller selector:

public class CustomControllerSelector : DefaultHttpControllerSelector
{
    public CustomControllerSelector(HttpConfiguration configuration)
        : base(configuration)
    { }

    public override string GetControllerName(HttpRequestMessage request)
    {
        var name = base.GetControllerName(request);

        // Interpret "LongClass" as "MyReallyLongNamedClass"
        if (name == "LongClass")
            name = "MyReallyLongNamedClass";

        return name;
    }
}

Then you can register the controller selector in your WebApiConfig.Register:

config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config));

The advantage of this is that you can use your already-mapped routes (defined using HttpRouteCollection.MapHttpRoute()) instead of using attribute routing. However, if you need to use attribute routing for other reasons anyways, then your solution is probably better.

0
votes

You don't have to worry about how the RoutePrefix attribute works internally. You can decorate either your controller or actions with RoutePrefix and can call the actions in accordance with your settings. You will have to use the Route atribute in your actions in order for [RoutePrefix] to work properly.

For example, in the below controller, all GET requests to url api/longclass/get will invoke the GetAll method and all POST requests to api/longclass/postwill invoke PostThis

[RoutePrefix("api/longclass")]
public class MyReallyLongNamedClass: ApiController
{
    [Route("get")]
    public string GetAll(int id)
    { 
        return "result";
    }

    [Route("post")] 
    public string PostThis([FromBody] MyModel model)
    {
       var res=  _repository.Save(model);
       return res;
    }
}