Как перенаправить действие MVC без возврата 301? (используя бета-версию MVC 4)

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

7
задан Morten Mertner 5 March 2012 в 15:07
поделиться