With the standard MapRoute method a can pass a string collection representing the namespaces in which to search for my controller. This seems to have dissapeared from MapHttpRoute. How does one define the default namespaces using the new API routing?
You're right -- they simply don't provide an extension method to accept the preferred namespaces. You can always go do this manually, or do something like this (not tried it myself):
var r = routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
r.DataTokens["Namespaces"] = new string[] {"Foo"};
namespace Client
{
public class DetailController : ApiController
{
.
.
.
}
}
namespace Order
{
public class DetailController : ApiController
{
.
.
.
}
}
//------------
// Global.asax
//------------
.
.
.
public static void RegisterRoutes(RouteCollection routes)
{
var Route1 = routes.MapHttpRoute
(
name: "ClientApi",
routeTemplate: "client/{controller}/{param1}"
);
Route1.DataTokens["Namespaces"] = new string[] {"Client"};
var Route2 = routes.MapHttpRoute
(
name: "OrderApi",
routeTemplate: "order/{controller}/{param1}"
);
Route2.DataTokens["Namespaces"] = new string[] { "Order" };
}
.
.
.
What I'm trying to do?
I want to make api calls like this:
http(s)://myapi/client/detail/PARAM1 --> supposed to "show" detail of CLIENT named PARAM1
http(s)://myapi/order/detail/PARAM1 --> supposed to "show" detail of ORDER named "PARAM1
As you see, there are two ApiControllers, "DetailController", have the same name but in different Namespaces. Compiler doesn't throw an error but when I make a call, "Multiple types were found that match the controller
named 'detail'. This can happen if the route that services this request ('client/{controller}/{param1}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the
'MapRoute' method that takes a 'namespaces' parameter. The request for 'detail' has found the following matching controllers: ...client.DetailController ...order.DetailController"
It suggests me to use MapRoute instead of MapHttpRoute.
I solved it by implementing my own IHttpControllerFactory (and injecting via an IDependencyResolver) and can now use areas and duplicate controller names (made unique by area). I could go further and do the namespaces thing.
It didn't seem that hard replacing this factory, looking at the DefaultHttpControllerFactory it looks like it maintaines a cache of controller name -> HttpControllerDescriptor. So you can check route data to see if it contains an area and use that to qualify
your key in your own cache.
r.DataTokens["Namespaces"] = new string[] {"Foo"};
That really didn't work for me in my scenario. I'll just wait until the next release. I'm sure it will get better then. It looks like from the code comments MapHttpRoute should be like MapRoute but just isn't quite done yet.
jwanga
Member
12 Points
7 Posts
How do I set the default namespaces in MapHttpRoute?
Feb 22, 2012 08:34 PM|LINK
With the standard MapRoute method a can pass a string collection representing the namespaces in which to search for my controller. This seems to have dissapeared from MapHttpRoute. How does one define the default namespaces using the new API routing?
raghuramn
Member
248 Points
64 Posts
Microsoft
Re: How do I set the default namespaces in MapHttpRoute?
Feb 22, 2012 09:38 PM|LINK
There is no default namespace. webapi searches for controllers from all the namespaces in the referenced dlls. A controller has to be
jwanga
Member
12 Points
7 Posts
Re: How do I set the default namespaces in MapHttpRoute?
Feb 22, 2012 09:51 PM|LINK
MSDN seems to allude that its possible. In the docs for MapHttpRoute the following is indicated:
"Maps the specified route template and sets default constraints, and namespaces."
http://msdn.microsoft.com/en-us/library/hh834863(v=vs.108).aspx
BrockAllen
All-Star
28082 Points
4996 Posts
MVP
Re: How do I set the default namespaces in MapHttpRoute?
Feb 23, 2012 04:55 PM|LINK
You're right -- they simply don't provide an extension method to accept the preferred namespaces. You can always go do this manually, or do something like this (not tried it myself):
var r = routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); r.DataTokens["Namespaces"] = new string[] {"Foo"};DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
jwanga
Member
12 Points
7 Posts
Re: How do I set the default namespaces in MapHttpRoute?
Feb 24, 2012 01:07 AM|LINK
Thanks, thats what i was looking for.
silgar
Member
16 Points
15 Posts
Re: How do I set the default namespaces in MapHttpRoute?
Feb 25, 2012 09:50 AM|LINK
Hi,
I have the same issue. This is my case:
namespace Client { public class DetailController : ApiController { . . . } } namespace Order { public class DetailController : ApiController { . . . } } //------------ // Global.asax //------------ . . . public static void RegisterRoutes(RouteCollection routes) { var Route1 = routes.MapHttpRoute ( name: "ClientApi", routeTemplate: "client/{controller}/{param1}" ); Route1.DataTokens["Namespaces"] = new string[] {"Client"}; var Route2 = routes.MapHttpRoute ( name: "OrderApi", routeTemplate: "order/{controller}/{param1}" ); Route2.DataTokens["Namespaces"] = new string[] { "Order" }; } . . .What I'm trying to do?
I want to make api calls like this:
http(s)://myapi/client/detail/PARAM1 --> supposed to "show" detail of CLIENT named PARAM1
http(s)://myapi/order/detail/PARAM1 --> supposed to "show" detail of ORDER named "PARAM1
As you see, there are two ApiControllers, "DetailController", have the same name but in different Namespaces. Compiler doesn't throw an error but when I make a call, "Multiple types were found that match the controller named 'detail'. This can happen if the route that services this request ('client/{controller}/{param1}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter. The request for 'detail' has found the following matching controllers: ...client.DetailController ...order.DetailController"
It suggests me to use MapRoute instead of MapHttpRoute.
How can I solve this problem?
LittleClive
Member
91 Points
65 Posts
Re: How do I set the default namespaces in MapHttpRoute?
Mar 15, 2012 09:42 AM|LINK
I solved it by implementing my own IHttpControllerFactory (and injecting via an IDependencyResolver) and can now use areas and duplicate controller names (made unique by area). I could go further and do the namespaces thing.
It didn't seem that hard replacing this factory, looking at the DefaultHttpControllerFactory it looks like it maintaines a cache of controller name -> HttpControllerDescriptor. So you can check route data to see if it contains an area and use that to qualify your key in your own cache.
trendoid
Member
7 Points
2 Posts
Re: How do I set the default namespaces in MapHttpRoute?
Mar 22, 2012 02:44 PM|LINK
r.DataTokens["Namespaces"] = new string[] {"Foo"};That really didn't work for me in my scenario. I'll just wait until the next release. I'm sure it will get better then. It looks like from the code comments MapHttpRoute should be like MapRoute but just isn't quite done yet.