So apparently there is some weird funky stuff where RouteTable.Routes.MapHttpRoute() adds the route to GlobalConfiguration.Configuration.Routes but the built in ApiExplorer does NOT pick them up.
Now if all the things ApiExplorer currently used werent INTERNAL I could just fix the ApiExplorer, but since MS wants to make my life harder I think I'll just fix the route creation instead.
AttributeRouting > https://github.com/mccalltd/AttributeRouting/ Works fairly well with one downside, it only adds routes to RouteCollection and does not support the IHttpRoute that is necessary
So in a nut shell, the way attribute routing works is it picks up all your routes from attributes and just calls routes.Add(). Simple? Right?
Well apparently something I am doing does not work.
This is what it boils down to:
private static void MapAttributeRoutesInternal(this HttpRouteCollection routes, HttpAttributeRoutingConfiguration configuration)
{
var generatedRoutes = new RouteBuilder(configuration).BuildAllRoutes();
generatedRoutes.ToList().ForEach(r =>
{
var route = routes.CreateRoute(r.Url, r.Defaults, r.Constraints, parameters: null);
routes.Add(r.RouteName, route);
});
}
Looks fine and dandy right? If you look at the extension method for MapHttpRoute on the HttpRouteCollection...
So far I have found out what the problem is. WebApi is converting my default constraints to another format.
Count:N
Keys: Array
Values: Array
And if you pass in a routevaluedictionary for the defaults, then it'll not convert it to that format.
Also the error is reported as a CONSTRAINT entry, but its NOT. its a DEFAULT entry. So that might be a type in the source. I haven't hunted it down yet.
Okay so I was mistaken. The Count one is the wrong one :P
This is because this third party code I have is generating the Dictionary for me, so I need to go around the GetTypeProperties that WebApi is running because I already did all the grunt work.
@digitalpacman: How did you fix this? I installed the AttributeRouting package from NUGET and the custom routes I have defined on my actions are not showing up in the collection of ApiDescriptions on the default ApiExplorer. For instance I have routes such
as
public class ProductsController{
[GET("api/Products/{id}/Categories")]
[HttpGet]
public Category[] Categories(string id)
{
//whatever
}
The above path does not show up in the ApiDescriptions contained in the ApiExplorer. Any ideas as to what additional configuration needs to be done to fix this?
digitalpacma...
Member
183 Points
148 Posts
Making AttributeRouting work with HttpRouteCollection
Jul 10, 2012 04:43 PM|LINK
Heyo,
So apparently there is some weird funky stuff where RouteTable.Routes.MapHttpRoute() adds the route to GlobalConfiguration.Configuration.Routes but the built in ApiExplorer does NOT pick them up.
Now if all the things ApiExplorer currently used werent INTERNAL I could just fix the ApiExplorer, but since MS wants to make my life harder I think I'll just fix the route creation instead.
AttributeRouting > https://github.com/mccalltd/AttributeRouting/
Works fairly well with one downside, it only adds routes to RouteCollection and does not support the IHttpRoute that is necessary
So in a nut shell, the way attribute routing works is it picks up all your routes from attributes and just calls routes.Add(). Simple? Right?
Well apparently something I am doing does not work.
This is what it boils down to:
private static void MapAttributeRoutesInternal(this HttpRouteCollection routes, HttpAttributeRoutingConfiguration configuration) { var generatedRoutes = new RouteBuilder(configuration).BuildAllRoutes(); generatedRoutes.ToList().ForEach(r => { var route = routes.CreateRoute(r.Url, r.Defaults, r.Constraints, parameters: null); routes.Add(r.RouteName, route); }); }Looks fine and dandy right? If you look at the extension method for MapHttpRoute on the HttpRouteCollection...
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints) { if (routes == null) { throw Error.ArgumentNull("routes"); } IHttpRoute route = routes.CreateRoute(routeTemplate, defaults, constraints, parameters: null); routes.Add(name, route); return route; }You will see it's the same exact stuff.
However!
When I run the extension method (first one) I get
Any ideas? I didn't add a constraint named "Count". There are only constraints for the http verbs supported.
digitalpacma...
Member
183 Points
148 Posts
Re: Making AttributeRouting work with HttpRouteCollection
Jul 10, 2012 05:08 PM|LINK
So far I have found out what the problem is. WebApi is converting my default constraints to another format.
Count:N
Keys: Array
Values: Array
And if you pass in a routevaluedictionary for the defaults, then it'll not convert it to that format.
Also the error is reported as a CONSTRAINT entry, but its NOT. its a DEFAULT entry. So that might be a type in the source. I haven't hunted it down yet.
digitalpacma...
Member
183 Points
148 Posts
Re: Making AttributeRouting work with HttpRouteCollection
Jul 10, 2012 05:28 PM|LINK
Okay so I was mistaken. The Count one is the wrong one :P
This is because this third party code I have is generating the Dictionary for me, so I need to go around the GetTypeProperties that WebApi is running because I already did all the grunt work.
digitalpacma...
Member
183 Points
148 Posts
Re: Making AttributeRouting work with HttpRouteCollection
Jul 10, 2012 05:35 PM|LINK
Figured it out.
If you are building your own then you need to call past their property conversion, stupid mistake by me. Wish I could delete this post.
var dataTokens = new Dictionary<string, object>(); var route = routes.CreateRoute(r.Url, r.Defaults, r.Constraints, dataTokens, null); routes.Add(r.RouteName, route);patelabhijee...
Member
4 Points
7 Posts
Re: Making AttributeRouting work with HttpRouteCollection
Feb 07, 2013 03:38 AM|LINK
@digitalpacman: How did you fix this? I installed the AttributeRouting package from NUGET and the custom routes I have defined on my actions are not showing up in the collection of ApiDescriptions on the default ApiExplorer. For instance I have routes such as
public class ProductsController{
[GET("api/Products/{id}/Categories")]
[HttpGet]
public Category[] Categories(string id)
{
//whatever
}
The above path does not show up in the ApiDescriptions contained in the ApiExplorer. Any ideas as to what additional configuration needs to be done to fix this?