Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 495
Priya Avatar asked Oct 18 '14 08:10

Priya


People also ask

Can we have two controllers with same name in MVC?

One should be of type Controller, and the other ApiController, then they can both exist with the same name.

What is the best controller for all Web API controllers to inherit from?

It's recommended that API controllers in ASP.NET Core inherit from ControllerBase and add the [ApiController] attribute. Standard view-based MVC controllers should inherit from Controller . In both frameworks, controllers are used to organize sets of action methods.

How do I find my controller name in Web API?

Look in the route dictionary for the key "controller". Take the value for this key and append the string "Controller" to get the controller type name. Look for a Web API controller with this type name.

What is difference between controller and API controller?

They work similarly in Web API, but controllers in Web API derive from the ApiController class instead of Controller class. The first major difference you will notice is that actions on Web API controllers do not return views, they return data. ApiControllers are specialized in returning data.


1 Answers

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:

  • http://server/api/v1/messages/{action}/{id}
  • http://server/api/v2/messages/{action}/{id}
  • http://server/api/messagesV1/{action}/{id}
  • http://server/api/messagesV2/{action}/{id}
  • http://server/api/{controller}/{action}/{id}

Hope that helps!

Steve

like image 111
Steve Avatar answered Sep 22 '22 19:09

Steve