回答

4

this

从本质上讲,你需要

private Type enumType; 

    public EnumConstraint(Type enumType) 
    { 
    this.enumType = enumType; 
    } 

    public bool Match(HttpContextBase httpContext, 
    Route route, 
    string parameterName,  
    RouteValueDictionary values, 
    RouteDirection routeDirection) 
    { 
    // You can also try Enum.IsDefined, but docs say nothing as to 
    // is it case sensitive or not. 
    return Enum.GetNames(enumType).Any(s => s.ToLowerInvariant() == values[parameterName].ToString()); 
    } 
+0

在我的博客上 - http://mikemilleresq.wordpress.com/2010/03/12/starting-small-mvc-constraints/ – 2011-06-07 09:43:06

+0

请参阅我的最终结果 – Jaap 2011-06-07 10:32:39

+0

'Enum.IsDefined()'区分大小写,所以应该避免,如果你的路由约束应该工作,无论大小写。 – Chris 2014-04-04 11:23:23

9

这是我想出了:

public class EnumRouteConstraint<T> : IRouteConstraint 
    where T : struct 
{ 

    private readonly HashSet<string> enumNames; 

    public EnumRouteConstraint() 
    { 
    string[] names = Enum.GetNames(typeof(T)); 
    enumNames = new HashSet<string>(from name in names select name.ToLowerInvariant()); 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
    return enumNames.Contains(values[parameterName].ToString().ToLowerInvariant()); 
    } 
} 

我认为一个HashSet将执行不是在每个Enum.GetNames好得多比赛。此外,使用泛型让您在使用约束时看起来更流畅。

不幸的是,编译器不允许使用T:Enum。

+1

*不幸的是,编译器不允许使用T:Enum *这是事实,但您仍然可以尝试在运行时强制执行它。 http://stackoverflow.com/a/2936591/242520 – 2013-07-03 05:54:12

+2

如果T不是枚举,则构造函数Enum.GetNames(typeof(T))将引发异常:ArgumentException:提供的类型必须是Enum。 – Jaap 2013-07-03 09:34:36

+1

这个效果很好。谢谢,@Jaap – Chris 2014-04-04 14:33:20