Получить список настраиваемых атрибутов для текущего действия/контроллера в ASP.NET MVC

Проверка кода примера из http://lukesampson.com/post/471548689/entering-and-exiting-https-with-asp-net-mvc, написанного для ASP.NET MVC2, я заметил, что они могут проверить, применяется ли специальный атрибут к текущее действие или контроллер путем доступа к filterContext.ActionDescriptor и filterContext.ActionDescriptor.ControllerDescriptor соответственно:

public class ExitHttpsIfNotRequiredAttribute : FilterAttribute, IAuthorizationFilter {
    public void OnAuthorization(AuthorizationContext filterContext) {
        // snip

        // abort if a [RequireHttps] attribute is applied to controller or action
        if(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return;
        if(filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return;

        // snip
    }
}

Каким будет метод ASP.NET MVC 1 для проверки действия и контроллера для настраиваемого атрибута? В ASP.NET MVC 1 нет filterContext.ActionDescriptor, что я могу сказать.

Ответ 1

Это похоже на работу... есть ли лучший/более правильный способ в ASP.NET MVC 1?

if (filterContext.Controller.GetType().GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0)
    return;
string action = (string)filterContext.RouteData.Values["action"];
if (!string.IsNullOrEmpty(action) && filterContext.Controller.GetType().GetMethod(action).GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0)
    return;

Ответ 2

Еще лучший и надежный * подход:

filterContext.ActionDescriptor.GetCustomAttributes(
    typeof(RequireHttpsAttribute), true).Count> 0

Хотя это может быть только MVC 3.0+.

Ответ 3

Goldplated edition, работает на MVC5, возможно 4/3:

filterContext.HasMarkerAttribute<RequireHttpsAttribute>()

Использует этот набор вспомогательных расширений:

public static class MarkerAttributeExtensions
{
    public static bool HasMarkerAttribute<T>(this AuthorizationContext that) {
        return that.Controller.HasMarkerAttribute<T>()
            || that.ActionDescriptor.HasMarkerAttribute<T>();
    }

    public static bool HasMarkerAttribute<T>(this ActionExecutingContext that) {
        return that.Controller.HasMarkerAttribute<T>()
            || that.ActionDescriptor.HasMarkerAttribute<T>();
    }

    public static bool HasMarkerAttribute<T>(this ControllerBase that) {
        return that.GetType().HasMarkerAttribute<T>();
    }

    public static bool HasMarkerAttribute<T>(this Type that) {
        return that.IsDefined(typeof(T), false);
    }

    public static IEnumerable<T> GetCustomAttributes<T>(this Type that) {
        return that.GetCustomAttributes(typeof(T), false).Cast<T>();
    }

    public static bool HasMarkerAttribute<T>(this ActionDescriptor that) {
        return that.IsDefined(typeof(T), false);
    }

    public static IEnumerable<T> GetCustomAttributes<T>(this ActionDescriptor that) {
        return that.GetCustomAttributes(typeof(T), false).Cast<T>();
    }
}