Priya
Priya

Reputation: 1425

Controllers With Same Name In Different NameSpace ASP.NET WEB API

I need to have controllers with same name in different namespace. The controllers I'm having are:

namespace BSB.Messages.Controllers.V1
{    
    public class MessagesController : ApiController {...}
}

namespace BSB.Messages.Controllers.V2
{       
    public class MessagesController : ApiController {...}
}

I tried to configure it in start up. But still when I make a call it shows error that:

Multiple types were found that match the controller named 'messages'. This can happen if the route that services this request ('api/{namespace}/{controller}/{action}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported

My Register function in WebApiConfig is :

public static void Register(HttpConfiguration config)
{
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute("DefaultApi", "api/{namespace}/{controller}/{action}/{id}", new { id = UrlParameter.Optional });
}

My RegisterRoutes function is:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    var r = routes.MapRoute(
                name: "Default",
                url: "v1/messages/{action}/{id}",
                defaults: new { id = UrlParameter.Optional },
                 namespaces: new[] { "BSB.Messages.Controllers.V1" }

            );
    r.DataTokens["Namespaces"] = new string[] { "BSB.Messages.Controllers.V1" };

    var r1 = routes.MapRoute(
               name: "V2",
               url: "v2/messages/{action}/{id}",
               defaults: new { id = UrlParameter.Optional },
               namespaces: new[] { "BSB.Messages.Controllers.V2" }
           );
    r1.DataTokens["Namespaces"] = new string[] { "BSB.Messages.Controllers.V2" };
}

I've called both functions from Global.asax

Can any one help me in this? What I've missed here?

Thanks,
Priya

Upvotes: 12

Views: 7310

Answers (1)

Steve
Steve

Reputation: 634

The second "RegisterRoutes" method applies only to MVC controllers not API controllers. API routing should be done in the WebAPI startup.

The line: config.MapHttpAttributeRoutes(); is going to work best for you, but will still require you to rename your controller classes. Take a look here for more on attribute routing: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

Which explains that you could decorate your classes with attributes that define your routes:

namespace BSB.Messages.Controllers.V1
{
    [RoutePrefix("api/v1/messages")]    
    public class MessagesV1Controller : ApiController {...}
}

namespace BSB.Messages.Controllers.V2
{      
    [RoutePrefix("api/v2/messages")] 
    public class MessagesV2Controller : ApiController {...}
}

And in your WebApi startup you could either get rid of the MapHTTPRoute calls and go attribute only, or:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    config.Routes.MapHttpRoute("DefaultApi", "api/v1/messages/{action}/{id}", new { controller = "MessagesV1", id = UrlParameter.Optional });
    config.Routes.MapHttpRoute("DefaultApi", "api/v2/messages/{action}/{id}", new { controller = "MessagesV2", id = UrlParameter.Optional });
    config.Routes.MapHttpRoute("DefaultApi", "api/{namespace}/{controller}/{action}/{id}", new { id = UrlParameter.Optional });
}

The above would result in the following working routes:

Hope that helps!

Steve

Upvotes: 9

Related Questions