How to simulate Server.Transfer in ASP.NET MVC?

后端 未结 14 1422
死守一世寂寞
死守一世寂寞 2020-11-22 12:00

In ASP.NET MVC you can return a redirect ActionResult quite easily :

 return RedirectToAction(\"Index\");

 or

 return RedirectToRoute(new { controller = \"         


        
相关标签:
14条回答
  • 2020-11-22 12:32

    For anyone using expression-based routing, using only the TransferResult class above, here's a controller extension method that does the trick and preserves TempData. No need for TransferToRouteResult.

    public static ActionResult TransferRequest<T>(this Controller controller, Expression<Action<T>> action)
        where T : Controller
    {
         controller.TempData.Keep();
         controller.TempData.Save(controller.ControllerContext, controller.TempDataProvider);
         var url = LinkBuilder.BuildUrlFromExpression(controller.Request.RequestContext, RouteTable.Routes, action);
         return new TransferResult(url);
    }
    
    0 讨论(0)
  • 2020-11-22 12:37

    Doesn't routing just take care of this scenario for you? i.e. for the scenario described above, you could just create a route handler that implemented this logic.

    0 讨论(0)
  • 2020-11-22 12:39

    I found out recently that ASP.NET MVC doesn't support Server.Transfer() so I've created a stub method (inspired by Default.aspx.cs).

        private void Transfer(string url)
        {
            // Create URI builder
            var uriBuilder = new UriBuilder(Request.Url.Scheme, Request.Url.Host, Request.Url.Port, Request.ApplicationPath);
            // Add destination URI
            uriBuilder.Path += url;
            // Because UriBuilder escapes URI decode before passing as an argument
            string path = Server.UrlDecode(uriBuilder.Uri.PathAndQuery);
            // Rewrite path
            HttpContext.Current.RewritePath(path, false);
            IHttpHandler httpHandler = new MvcHttpHandler();
            // Process request
            httpHandler.ProcessRequest(HttpContext.Current);
        }
    
    0 讨论(0)
  • 2020-11-22 12:40

    You could new up the other controller and invoke the action method returning the result. This will require you to place your view into the shared folder however.

    I'm not sure if this is what you meant by duplicate but:

    return new HomeController().Index();
    

    Edit

    Another option might be to create your own ControllerFactory, this way you can determine which controller to create.

    0 讨论(0)
  • 2020-11-22 12:41

    You can use Server.TransferRequest on IIS7+ instead.

    0 讨论(0)
  • 2020-11-22 12:44

    Edit: Updated to be compatible with ASP.NET MVC 3

    Provided you are using IIS7 the following modification seems to work for ASP.NET MVC 3. Thanks to @nitin and @andy for pointing out the original code didn't work.

    Edit 4/11/2011: TempData breaks with Server.TransferRequest as of MVC 3 RTM

    Modified the code below to throw an exception - but no other solution at this time.


    Here's my modification based upon Markus's modifed version of Stan's original post. I added an additional constructor to take a Route Value dictionary - and renamed it MVCTransferResult to avoid confusion that it might just be a redirect.

    I can now do the following for a redirect:

    return new MVCTransferResult(new {controller = "home", action = "something" });
    

    My modified class :

    public class MVCTransferResult : RedirectResult
    {
        public MVCTransferResult(string url)
            : base(url)
        {
        }
    
        public MVCTransferResult(object routeValues):base(GetRouteURL(routeValues))
        {
        }
    
        private static string GetRouteURL(object routeValues)
        {
            UrlHelper url = new UrlHelper(new RequestContext(new HttpContextWrapper(HttpContext.Current), new RouteData()), RouteTable.Routes);
            return url.RouteUrl(routeValues);
        }
    
        public override void ExecuteResult(ControllerContext context)
        {
            var httpContext = HttpContext.Current;
    
            // ASP.NET MVC 3.0
            if (context.Controller.TempData != null && 
                context.Controller.TempData.Count() > 0)
            {
                throw new ApplicationException("TempData won't work with Server.TransferRequest!");
            }
    
            httpContext.Server.TransferRequest(Url, true); // change to false to pass query string parameters if you have already processed them
    
            // ASP.NET MVC 2.0
            //httpContext.RewritePath(Url, false);
            //IHttpHandler httpHandler = new MvcHttpHandler();
            //httpHandler.ProcessRequest(HttpContext.Current);
        }
    }
    
    0 讨论(0)
提交回复
热议问题