Reputation: 10014
Since areas are not easily supported in Web API (and also because I need more flexibility than project-wide routing rules), I am using the [RoutePrefix]
attribute on my controllers to group my Web API controllers into namespaces, e.g.:
[RoutePrefix["Namespace1/Controller1"]
public class Controller1 : ApiControllerBase { }
[RoutePrefix["Namespace1/Controller2"]
public class Controller2 : ApiControllerBase { }
[RoutePrefix["Namespace1/Controller3"]
public class Controller3 : ApiControllerBase { }
[RoutePrefix["Namespace2/Controller4"]
public class Controller4 : ApiControllerBase { }
[RoutePrefix["Namespace2/Controller5"]
public class Controller5 : ApiControllerBase { }
[RoutePrefix["Namespace2/Controller6"]
public class Controller6 : ApiControllerBase { }
(These are in separate files and contain actions within them, I just removed that, along with actual names, for simplicity.)
I am generating help documentation using Web API Help Pages, which works fine. However, I would like to group and order the documentation by my "namespaces" (group by route prefix, then sort alphabetically within each).
I decided to start out by just ordering and then figure out the grouping once I get the ordering to work. To get the ordering to work, I tried altering my Index.cshtml
[in the HelpPage
area created by the Web API Help Page Nuget package] from this:
@foreach (IGrouping<HttpControllerDescriptor, ApiDescription> group in apiGroups)
{
@Html.DisplayFor(m => group, "ApiGroup")
}
to this:
@foreach (IGrouping<HttpControllerDescriptor, ApiDescription> group
in apiGroups.OrderBy(g => g.Key.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault().Prefix)
.ThenBy(g => g.Key.ControllerName))
{
@Html.DisplayFor(m => group, "ApiGroup")
}
However, I get a null reference exception: in the LINQ expression above, g.Key.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault()
is null for all my controllers. This doesn't make any sense to me because the routing itself is working correctly (including the prefix). Any suggestions?
Upvotes: 4
Views: 3868
Reputation: 13183
To elaborate on the answer from chris, I was able to get it working with the following code block. I am using Web API 2.2 (version 5.1.2)
@foreach (IGrouping<HttpControllerDescriptor, ApiDescription> group in apiGroups
.OrderBy(g => g.Key.ControllerType.GetCustomAttributes<System.Web.Http.RoutePrefixAttribute>().FirstOrDefault().Prefix)
.ThenBy(g => g.Key.ControllerName))
{
@Html.DisplayFor(m => group, "ApiGroup")
}
You'll need to add
@using System.Reflection
to the top of the file in order to get the generic GetCustomAttributes
extension method into scope.
Upvotes: 2
Reputation: 2621
Had the same issue recently ... there is a minor error in your LINQ expression.
apiGroups.OrderBy(g => g.Key.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault().Prefix)
should read:
apiGroups.OrderBy(g => g.Key.ControllerType.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault().Prefix)
This works for me, anyway.
Upvotes: 2