2015-03-16 3 views
2

Итак, я создал свой собственный ControllerFactory, и я перегружаю GetControllerSessionBehavior, чтобы расширить поведение MVC.RequestContext - RouteData не содержит действия

Чтобы выполнить свою собственную работу, я должен использовать отражение на вызываемом действии. Однако я наткнулся на странный вопрос - я не могу получить действие путем доступа RequestContext.RouteData

При настройке образца воспроизведения для этого я не был в состоянии воспроизвести ошибку.

Кто-нибудь знает о возможных причинах этого или знает, как получить действие, вызвав метод с другим контекстом запроса, кроме этого?

public class CustomControllerFactory : DefaultControllerFactory 
{ 
    protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType) 
    { 
     if (!requestContext.RouteData.Values.ContainsKey("action")) 
      return base.GetControllerSessionBehavior(requestContext, controllerType); 

     var controllerAction = requestContext.RouteData.Values["action"]; 
     var action = controllerAction.ToString(); 

     var actionMethod = controllerType.GetMember(action, MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(); 
     if(actionMethod == null) 
      return base.GetControllerSessionBehavior(requestContext, controllerType); 

     var cattr = actionMethod.GetCustomAttribute<SessionStateActionAttribute>(); 
     if (cattr != null) 
      return cattr.Behavior; 

     return base.GetControllerSessionBehavior(requestContext, controllerType); 
    } 
} 

Действие, которое я могу назвать только штраф, но не может получить доступ к имени действия в рамках моего контроллера завода:

[Route("Open/{createModel:bool?}/{tlpId:int}/{siteId:int?}")] 
    public ActionResult Open(int tlpId, int? siteId, bool? createModel = true) 
    { 
    } 

Любые идеи приветствуются.

Update:

Проблема, как представляется, связаны с атрибутом маршрутизации. Пока он работает нормально, он не работает для меня.

Обнаружено это в пути - после ответа this я также получу свое надлежащее решение.

Update 2:

Интересно. Воспроизведение MVC Version 5.0.0.0, Production 5.2.2. Возможное введение ошибки?

+0

В чем проблема? Does 'requestContext.RouteData.Values ​​[" action "]' возвращает 'null'? – haim770

+0

да. в зависимости от версии mvc – Dbl

ответ

4

Я могу подтвердить, что произошла перерыв в атрибуте маршрутизации между 5.0.0 и 5.1.1. Я сообщил об ошибке here. Однако для моего случая использования Microsoft смогла обеспечить приемлемое обходное решение.

С другой стороны, проблема, с которой вы сталкиваетесь, выглядит как другой преступник. Для маршрутизации атрибутов значения маршрута хранятся в вложенном ключе ключа с именем MS_DirectRouteMatches. Я точно не знаю, какая версия изменилась, но я знаю, что это произошло v5 +.

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

var routeData = requestContext.RouteData; 
if (routeData.Values.ContainsKey("MS_DirectRouteMatches")) 
{ 
    routeData = ((IEnumerable<RouteData>)routeData.Values["MS_DirectRouteMatches"]).First(); 
} 
var controllerAction = routeData.Values["action"]; 
var action = controllerAction.ToString(); 

BTW - В linked question вы предоставили, Аскер предполагается, что существует вероятность того, где запрос может соответствовать более одного маршрута. Но это невозможно - запрос будет соответствовать 0 или 1 маршруту, но не более одного.

+1

Причина Закрыт: \t По дизайну. Вау. Это лениво. очевидно, не работает по назначению ... да. Я применил это обходное решение – Dbl

Смежные вопросы