MVC4 Web API–REST Sub-resources

To create sub-resources (e.g. /books/1/authors) in the Web API that shipped with MVC beta 4, you can create a “SubResourceControllerFactory” to mangle the controller name to include a sub controller as follows:

public class SubResourceControllerFactory : DefaultHttpControllerFactory
{
    public SubResourceControllerFactory(HttpConfiguration configuration) : base(configuration)
    {
    }

    public override System.Web.Http.Controllers.IHttpController CreateController(System.Web.Http.Controllers.HttpControllerContext controllerContext, string controllerName)
    {
        if (controllerContext.RouteData.Values.ContainsKey("subcontroller"))
        {
            return base.CreateController(controllerContext, controllerName + controllerContext.RouteData.Values["subcontroller"]);
        }

        return base.CreateController(controllerContext, controllerName);
    }
}

This factory can be instantiated using a custom IDependencyResolver that’s looking for a type of IHttpControllerFactory, for example in Global.asax.cs (Application_Start):

GlobalConfiguration.Configuration.ServiceResolver.SetResolver((type) =>
    {
        if (type == typeof(IHttpControllerFactory))
        {
            return new SubResourceControllerFactory();
        }
    });

Finally you create a route similar to:

routeCollection.MapHttpRoute("SubController", "api/{controller}/{id}/{subcontroller}/{subId}", new { subId = RouteParameter.Optional })

Advertisements

3 thoughts on “MVC4 Web API–REST Sub-resources

  1. Thanks for this post. I am trying to implement sub-resources in my web API. I am trying to the approach you have suggested but not able to understand how to achieve this:

    “This factory can be instantiated using a custom IDependencyResolver that’s looking for a type of IHttpControllerFactory.”

    I would highly appreciate a code snippet to explain this.

    Thanks,

  2. Thanks for the reply.

    I have written the implementation for SubControllerFactory class as above and have the code in Global.asax.cs (Application_Start):

    GlobalConfiguration.Configuration.ServiceResolver.SetResolver((type) =>
    {
    if (type == typeof(IHttpControllerFactory))
    {
    return new SubResourceControllerFactory();
    }
    });

    I am getting error “Cannot convert lambda expression to type ‘object’ because it is not a delegate type” upon compilation.

    I am new to MVC and not able to resolve this error. Please let me know if anything missing from my code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s