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

前端之家收集整理的这篇文章主要介绍了c# – 如何在不返回301的情况下重定向MVC操作? (使用MVC 4 beta)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在开发一个ASP.NET MVC解决方案,它有许多不同的菜单.要显示菜单取决于当前登录用户的角色.

在MVC 3中,我有一些自定义代码支持这种情况,通过一个单一的控制器方法返回正确的菜单.它会通过将请求推迟到适当的控制器和操作来执行此操作,具体取决于当前用户.

代码似乎在MVC 4中被破坏,我正在寻求帮助来解决它.

首先,我添加了一个TransferResult助手类来执行重定向

  1. public class TransferResult : RedirectResult
  2. {
  3. #region Transfer to URL
  4. public TransferResult( string url ) : base( url )
  5. {
  6. }
  7. #endregion
  8.  
  9. #region Transfer using RouteValues
  10. public TransferResult( object routeValues ) : base( GetRouteUrl( routeValues ) )
  11. {
  12. }
  13.  
  14. private static string GetRouteUrl( object routeValues )
  15. {
  16. var url = new UrlHelper( new RequestContext( new HttpContextWrapper( HttpContext.Current ),new RouteData() ),RouteTable.Routes );
  17. return url.RouteUrl( routeValues );
  18. }
  19. #endregion
  20.  
  21. #region Transfer using ActionResult (T4MVC only)
  22. public TransferResult( ActionResult result ) : base( GetRouteUrl( result.GetT4MVCResult() ) )
  23. {
  24. }
  25.  
  26. private static string GetRouteUrl( IT4MVCActionResult result )
  27. {
  28. var url = new UrlHelper( new RequestContext( new HttpContextWrapper( HttpContext.Current ),RouteTable.Routes );
  29. return url.RouteUrl( result.RouteValueDictionary );
  30. }
  31. #endregion
  32.  
  33. public override void ExecuteResult( ControllerContext context )
  34. {
  35. HttpContext httpContext = HttpContext.Current;
  36. httpContext.RewritePath( Url,false );
  37. IHttpHandler httpHandler = new MvcHttpHandler();
  38. httpHandler.ProcessRequest( HttpContext.Current );
  39. }
  40. }

其次,我修改了T4MVC以发出一些控制器辅助方法,导致每个控制器都有这种方法

  1. protected TransferResult Transfer( ActionResult result )
  2. {
  3. return new TransferResult( result );
  4. }

这使我可以使用共享控制器操作来返回菜单,而不必使用任何条件逻辑来混淆视图:

  1. public virtual ActionResult Menu()
  2. {
  3. if( Principal.IsInRole( Roles.Administrator ) )
  4. return Transfer( MVC.Admin.Actions.Menu() );
  5. return View( MVC.Home.Views.Partials.Menu );
  6. }

但是,TransferResult类中的ExecuteResult中的代码似乎不适用于MVC 4的当前预览版本.它给出了以下错误(指向“httpHandler.ProcessRequest”行):

  1. 'HttpContext.SetSessionStateBehavior' can only be invoked before
  2. 'HttpApplication.AcquireRequestState' event is raised.

知道如何解决这个问题吗?

PS:我意识到我可以使用简单的HtmlHelper扩展来实现相同的功能,这是我目前正在使用的解决方法.但是,我还有许多其他场景,这种方法允许我混合和重用动作,我不想在转移到MVC 4时放弃这种灵活性.

解决方法@H_403_28@
有时我认为“MVC”应该被称为“RCMV”用于“路由器控制器模型视图”,因为这确实是事情发生的顺序.此外,由于它只是“MVC”,人们总是倾向于忘记路由. MVC的优点在于路由可配置和可扩展.我相信你想要做的事情可以通过自定义路由处理程序来解决.

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

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

然后您的路由处理程序将如下所示:

  1. public class MyRouteHandler : IRouteHandler
  2. {
  3. public string Role { get; set; }
  4.  
  5. public object RouteValues { get; set; }
  6.  
  7. public MyRouteHandler(string role,object routeValues)
  8. {
  9. Role = role;
  10. RouteValues = routeValues;
  11. }
  12.  
  13. public IHttpHandler GetHttpHandler(RequestContext requestContext)
  14. {
  15. return new MyHttpHandler(Role,RouteValues);
  16. }
  17. }

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

  1. public class MyHttpHandler : IHttpHandler
  2. {
  3. public string Role { get; set; }
  4.  
  5. public object RouteValues { get; set; }
  6.  
  7. public MyHttpHandler(string role,object routeValues)
  8. {
  9. Role = role;
  10. RouteValues = routeValues;
  11. }
  12.  
  13. public void ProcessRequest(HttpContext httpContext)
  14. {
  15. if (httpContext.User.IsInRole(Role))
  16. {
  17. RouteValueDictionary routeValues = new RouteValueDictionary(RouteValues);
  18.  
  19. // put logic here to create path similar to what you were doing
  20. // before but you will need to replace any keys in your route
  21. // with the values from the dictionary created above.
  22.  
  23. httpContext.RewritePath(path);
  24. }
  25.  
  26. IHttpHandler handler = new MvcHttpHandler();
  27. handler.ProcessRequest(httpContext);
  28. }
  29. }

这可能不是100%正确,但它应该以一种不应该遇到MVC4中弃用的任何东西的方式让你朝着正确的方向前进.

猜你在找的C#相关文章