由于Web API中不容易支持区域(并且因为我需要比项目范围的路由规则更多的灵活性),所以我在控制器上使用[RoutePrefix]
属性将我的Web API控制器分组到命名空间中,例如:
[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 { }
(这些是在单独的文件中并包含其中的操作,为了简单起见,我只是将其与实际名称一起删除。)
我正在使用Web API帮助页面生成帮助文档,该工作正常。但是,我想通过我的“命名空间”对文档进行分组和排序(按路径前缀分组,然后按字母顺序排序)。
我决定从订购开始,然后在我下订单工作后找出分组。为了让订单起作用,我尝试改变我的Index.cshtml
[在Web API帮助页面Nuget包创建的HelpPage
区域]中:
@foreach (IGrouping<HttpControllerDescriptor, ApiDescription> group in apiGroups)
{
@Html.DisplayFor(m => group, "ApiGroup")
}
到此:
@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")
}
但是,我得到一个空引用异常:在上面的LINQ表达式中,g.Key.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault()
对于我的所有控制器都为null。这对我没有任何意义,因为路由本身工作正常(包括前缀)。有什么建议吗?
答案 0 :(得分:2)
最近有同样的问题......你的LINQ表达式中有一个小错误。
apiGroups.OrderBy(g => g.Key.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault().Prefix)
应为:
apiGroups.OrderBy(g => g.Key.ControllerType.GetCustomAttributes<RoutePrefixAttribute>().FirstOrDefault().Prefix)
无论如何,这对我有用。
答案 1 :(得分:2)
为了详细说明克里斯的答案,我能够使用以下代码块。我正在使用Web API 2.2(版本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")
}
您需要添加
@using System.Reflection
到文件的顶部,以便将通用GetCustomAttributes
扩展方法放入范围。