AttributeRouting - 从RouteData获取动作名称的正确方法

时间:2014-12-02 08:54:59

标签: asp.net-mvc asp.net-mvc-routing attributerouting

我最近开始为我的动作方法使用属性路由,并且很难从RouteData获取动作名称(和/或id)。下面是我如何使用attrubues的例子:

[Route( "Edit/{id:int}" )]
public ActionResult Edit( int id )
{
    ...
}

以前我使用以下方法作为RouteData的扩展来检索值

public static string GetActionName( this RouteData routeData )
{
    return routeData.Values[ "Action" ] as string;
}

这用于返回操作名称(在此示例中为"编辑")。现在这总是返回null。对RouteData字典的检查表明,这些值似乎不再放在数组的根中,而是放在键入的项目中,并且#34; [0] =" MS_DirectRouteMatches"。

我可以通过以下方式访问此值,但由于我对如何填充这些值的理解有限,我担心,例如,在有多个匹配的路由中,此代码在某些情况下会失效。

public static string GetActionName( this RouteData routeData )
{
    if( routeData.Values.ContainsKey( "MS_DirectRouteMatches" ) )
        routeData = ( ( IList<RouteData> )routeData.Values[ "MS_DirectRouteMatches" ] )[ 0 ];

    return routeData.Values[ "Action" ] as string;
}

访问由AttributeRouting填充的RouteData值的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

除一种情况外,您的解决方案将适用于所有情况。请求可能与任何路由都不匹配,因此您应该在返回之前确保action密钥存在,否则您可能会遇到异常。

public static string GetActionName( this RouteData routeData )
{
    if( routeData.Values.ContainsKey( "MS_DirectRouteMatches" ) )
        routeData = ( ( IEnumerable<RouteData> )routeData.Values["MS_DirectRouteMatches"] )[0];

    return routeData.Values.ContainsKey("action") ? 
        routeData.Values["action"] as string : 
        string.Empty;
}

这种情况通常会将请求传递给IIS,因此它可以返回404页面(如果已配置,则返回自定义页面),这基本上只涵盖自定义404页面案例。

我还要将IList更改为IEnumerable,因为您没有向方法中的列表添加任何内容。

没有匹配多条路线的请求(0或1路线是唯一的可能性)。如果没有匹配项,则MS_DirectRouteMatches将不存在。在它确实存在的情况下,集合中有1个值。

不幸的是,在未来的版本中,集合中的值数量不会变为多个,但实际上并没有任何保证,但现在这种情况仍然适用。但是,由于没有比这更稳健的方法来确定一个动作名称,这是我们在下一次重大改变之前所坚持的。