Я работаю над решением ASP.NET MVC, которое имеет несколько различных меню. Отображаемое меню зависит от роли текущего пользователя, вошедшего в систему.
В MVC 3 у меня был некоторый собственный код для поддержки этого сценария с помощью одного метода контроллера, который возвращал бы правильное меню. Это будет сделано путем откладывания запроса на соответствующий контроллер и действия в зависимости от текущего пользователя.
Похоже, этот код не работает в MVC 4, и мне нужна помощь, чтобы исправить это.
Во-первых, я добавил вспомогательный класс TransferResult для выполнения перенаправления:
public class TransferResult : RedirectResult
{
#region Transfer to URL
public TransferResult( string url ) : base( url )
{
}
#endregion
#region Transfer using RouteValues
public TransferResult( object routeValues ) : base( GetRouteUrl( routeValues ) )
{
}
private static string GetRouteUrl( object routeValues )
{
var url = new UrlHelper( new RequestContext( new HttpContextWrapper( HttpContext.Current ), new RouteData() ), RouteTable.Routes );
return url.RouteUrl( routeValues );
}
#endregion
#region Transfer using ActionResult (T4MVC only)
public TransferResult( ActionResult result ) : base( GetRouteUrl( result.GetT4MVCResult() ) )
{
}
private static string GetRouteUrl( IT4MVCActionResult result )
{
var url = new UrlHelper( new RequestContext( new HttpContextWrapper( HttpContext.Current ), new RouteData() ), RouteTable.Routes );
return url.RouteUrl( result.RouteValueDictionary );
}
#endregion
public override void ExecuteResult( ControllerContext context )
{
HttpContext httpContext = HttpContext.Current;
httpContext.RewritePath( Url, false );
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest( HttpContext.Current );
}
}
Во-вторых, я изменил T4MVC, чтобы он выдавал несколько вспомогательных методов контроллера, в результате чего каждый контроллер имел этот метод:
protected TransferResult Transfer( ActionResult result )
{
return new TransferResult( result );
}
Это позволило мне иметь общий действие контроллера для возврата меню без необходимости загромождать представления какой-либо условной логикой:
public virtual ActionResult Menu()
{
if( Principal.IsInRole( Roles.Administrator ) )
return Transfer( MVC.Admin.Actions.Menu() );
return View( MVC.Home.Views.Partials.Menu );
}
Однако код в ExecuteResult в классе TransferResult, похоже, не работает с текущим предварительным выпуском MVC 4. Это дает мне следующее ошибка (указывая на строку «httpHandler.ProcessRequest»):
'HttpContext.SetSessionStateBehavior' can only be invoked before
'HttpApplication.AcquireRequestState' event is raised.
Есть идеи, как это исправить?
PS: Я понимаю, что могу добиться того же, используя простое расширение HtmlHelper, которое я сейчас использую в качестве обходного пути. Однако у меня есть много других сценариев, в которых этот метод позволяет мне смешивать и повторно использовать действия, и мне бы очень не хотелось отказываться от этой гибкости при переходе на MVC 4.