回答

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