2009-05-20 1 views
1

У меня есть настраиваемый ViewEngine, и я хочу изменить основную страницу, используемую в зависимости от того, имеет ли запрошенное действие фильтр атрибутов Authorize.Найти atrributes в действии из ViewEngine в ASP.NET MVC

До сих пор я только с помощью отражения, как это:

var method = controllerContext.Controller.GetType().GetMethod(viewName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); 
if (method != null) 
{ 
    if (method.GetCustomAttributes(typeof(AuthorizeAttribute), true).Length > 0) 
    { 
     masterName = "Admin.master"; 
    } 
} 

Но я не большой поклонник с помощью отражения для повторяющихся задач. Я знаю, что я могу использовать кеш-представление для ускорения работы после первого раза, но мне интересно, есть ли более прямой способ получить доступ к списку фильтров, применяемых к действию внутри метода FindViewViewEngine?

ответ

1

В значительной степени ограничивается использование отражения для получения любой информации об атрибутах независимо от чего-либо, включая методы действия MVC. ;)

Единственный метод, чтобы получить эту информацию, чтобы пройти через ControllerDescriptor аллеи

В вашем случае вы можете просто пропустить ищете атрибут авторизовать на все и просто просите, если пользователь авторизован или нет, и предоставляя им главную страницу, в которой они нуждаются.

Я установил основную страницу динамически в пользовательский механизм просмотра, и наиболее эффективная опция - посмотреть, какая информация HttpContextBase доступна. Для одного сценария я просто передавал параметры запроса или добавлял параметры маршрута {masterPage}, когда мне нужно их использовать.

Единственная другая информация о пути к действию - это маршрут ReflectedControllerDescriptor. Проблема с этим методом - очень многословная и требует много строк кода, чтобы делать то, что вы делаете.

Вот немного кода (я нашел на stackoverflow!) Этого метода «дескриптора» для обрезки обрезки линии защиты. Этот код также можно использовать для динамического задания главной страницы, если она была в настраиваемом механизме просмотра. Это не то, что вы ищете, но может помочь кому-то другому выполнить такую ​​же настройку динамической мастер-страницы где-то еще:

public static bool HasActionPermission(this HtmlHelper htmlHelper, string actionName, string controllerName) 
    { 
     //if the controller name is empty the ASP.NET convention is: 
     //"we are linking to a different controller 
     ControllerBase controllerToLinkTo = string.IsNullOrEmpty(controllerName) 
               ? htmlHelper.ViewContext.Controller 
               : GetControllerByName(htmlHelper, controllerName); 

     var controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerToLinkTo); 

     var controllerDescriptor = new ReflectedControllerDescriptor(controllerToLinkTo.GetType()); 

     var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); 

     return ActionIsAuthorized(controllerContext, actionDescriptor); 
    } 


    private static bool ActionIsAuthorized(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
    { 
     if (actionDescriptor == null) 
      return false; // action does not exist so say yes - should we authorise this?! 

     AuthorizationContext authContext = new AuthorizationContext(controllerContext); 

     // run each auth filter until on fails 
     // performance could be improved by some caching 
     foreach (IAuthorizationFilter authFilter in actionDescriptor.GetFilters().AuthorizationFilters) 
     { 
      authFilter.OnAuthorization(authContext); 

      if (authContext.Result != null) 
       return false; 
     } 

     return true; 
    } 
Смежные вопросы