【发布时间】:2012-03-22 12:16:22
【问题描述】:
我正在开发一个具有许多不同菜单的 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 );
}
但是,TransferResult 类中的 ExecuteResult 中的代码似乎不适用于当前的 MVC 4 预览版。它给了我以下错误(指向“httpHandler.ProcessRequest”行):
'HttpContext.SetSessionStateBehavior' can only be invoked before
'HttpApplication.AcquireRequestState' event is raised.
知道如何解决这个问题吗?
PS:我意识到我可以使用一个简单的 HtmlHelper 扩展来实现相同的目的,这是我目前用作解决方法的方法。但是,我在许多其他情况下,这种方法允许我混合和重用动作,我不愿意在迁移到 MVC 4 时放弃这种灵活性。
【问题讨论】:
-
您应该将该方法放在
Controller基类中,而不是在每个控制器中。 -
@SLaks 这似乎是一个微优化,因为代码是由 T4MVC 生成的,而且它只是一个单行代码。也没有做任何事情来帮助解决问题;)
-
一定是慢节奏的一天;甚至无法获得赞成票 :o)
标签: c# asp.net-mvc asp.net-mvc-4 t4mvc