Я работаю над решением 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.