Web API帮助页面 - 按路径前缀订购控制器

时间:2013-11-01 16:55:51

标签: asp.net-web-api asp.net-web-api-routing asp.net-web-api-helppages

由于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。这对我没有任何意义,因为路由本身工作正常(包括前缀)。有什么建议吗?

2 个答案:

答案 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扩展方法放入范围。