Estoy trabajando en una solución ASP.NET MVC que tiene varios menús diferentes. El menú para mostrar depende del rol del usuario que está conectado actualmente.¿Cómo redirigir la acción MVC sin devolver 301? (usando MVC 4 beta)
En MVC 3 tenía un código personalizado para admitir este escenario, al tener un único método de controlador que devolvería el menú correcto. Haría esto posponiendo la solicitud al controlador apropiado y a la acción dependiendo del usuario actual.
Este código parece estar roto en MVC 4 y estoy buscando ayuda para solucionarlo.
En primer lugar, añade una clase TransferResult ayudante para realizar la redirección:
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);
}
}
En segundo lugar, he modificado T4MVC para emitir algunos métodos controlador de ayuda, que resulta en cada controlador que tiene este método:
protected TransferResult Transfer(ActionResult result)
{
return new TransferResult(result);
}
Esto me permitió tener una acción de controlador compartido para devolver un menú, sin tener que saturar las vistas con ninguna lógica condicional:
public virtual ActionResult Menu()
{
if(Principal.IsInRole(Roles.Administrator))
return Transfer(MVC.Admin.Actions.Menu());
return View(MVC.Home.Views.Partials.Menu);
}
Sin embargo, no parece funcionar con la versión preliminar actual de MVC 4. Me da el siguiente error (apuntando a la línea "httpHandler.ProcessRequest") el código en ExecuteResult en la clase TransferResult:
'HttpContext.SetSessionStateBehavior' can only be invoked before
'HttpApplication.AcquireRequestState' event is raised.
¿Alguna idea de cómo solucionar esto?
PD: Me doy cuenta de que podría lograr lo mismo con una simple extensión HtmlHelper, que es lo que estoy usando actualmente como solución alternativa. Sin embargo, tengo muchos otros escenarios donde este método me ha permitido mezclar y reutilizar acciones, y odiaría renunciar a esta flexibilidad cuando me muevo a MVC 4.
Usted debe poner ese método en una base de clase' controlador', no en todos los controladores de – SLaks
@SLaks Eso parece ser un micro-optimización teniendo en cuenta que el código es generado por T4MVC y es solo un trazador de líneas. Tampoco hace nada para ayudar a resolver el problema;) –
Debe ser un día lento; ni siquiera puede obtener un voto positivo: o) –