gpt4 book ai didi

c# - 如何在不返回 301 的情况下重定向 MVC 操作? (使用 MVC 4 测试版)

转载 作者:太空狗 更新时间:2023-10-29 20:25:05 30 4
gpt4 key购买 nike

我正在开发一个具有许多不同菜单的 ASP.NET MVC 解决方案。要显示的菜单取决于当前登录用户的角色。

在 MVC 3 中,我有一些自定义代码来支持这种情况,方法是使用一个可以返回正确菜单的 Controller 方法。它会根据当前用户将请求延迟到适当的 Controller 和操作来执行此操作。

这段代码似乎在 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 以发出一些 Controller 辅助方法,导致每个 Controller 都有此方法:

protected TransferResult Transfer( ActionResult result )
{
return new TransferResult( result );
}

这让我有一个共享的 Controller 操作来返回一个菜单,而不必用任何条件逻辑使 View 困惑:

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 时放弃这种灵 active 。

最佳答案

有时我认为“MVC”应该称为“路由器 Controller 模型 View ”的“RCMV”,因为这确实是事情发生的顺序。此外,由于它只是“MVC”,人们总是倾向于忘记路由。 MVC 的伟大之处在于路由可配置和可扩展。我相信您正在尝试做的事情可以通过自定义路由处理程序来解决。

我还没有测试过这个,但是你应该可以这样做:

routes.Add(
new Route(
"{controller}/{action}/{id}",
new RouteValueDictionary(new { controller = "Home", action = "Menu" }),
new MyRouteHandler(Roles.Administrator, new { controller = "Admin" })));

然后你的路由处理器看起来像这样:

public class MyRouteHandler : IRouteHandler
{
public string Role { get; set; }

public object RouteValues { get; set; }

public MyRouteHandler(string role, object routeValues)
{
Role = role;
RouteValues = routeValues;
}

public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MyHttpHandler(Role, RouteValues);
}
}

最后在你的 HttpHandler 中处理重新路由:

public class MyHttpHandler : IHttpHandler
{
public string Role { get; set; }

public object RouteValues { get; set; }

public MyHttpHandler(string role, object routeValues)
{
Role = role;
RouteValues = routeValues;
}

public void ProcessRequest(HttpContext httpContext)
{
if (httpContext.User.IsInRole(Role))
{
RouteValueDictionary routeValues = new RouteValueDictionary(RouteValues);

// put logic here to create path similar to what you were doing
// before but you will need to replace any keys in your route
// with the values from the dictionary created above.

httpContext.RewritePath(path);
}

IHttpHandler handler = new MvcHttpHandler();
handler.ProcessRequest(httpContext);
}
}

这可能不是 100% 正确,但它应该以一种不应该遇到 MVC4 中弃用的任何方式的方式引导您朝着正确的方向前进。

关于c# - 如何在不返回 301 的情况下重定向 MVC 操作? (使用 MVC 4 测试版),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9559642/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com