Alternative to Server.Transfer in ASP.NET Core

前端 未结 3 998
我在风中等你
我在风中等你 2020-12-31 16:14

I am migrating an ASP.NET application to ASP.NET Core and they have some calls to HttpServerUtility.Transfer(string path). However, HttpServerUtility does not

3条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-31 16:55

    You are correct. Server.Transfer and Server.Redirect are quite different. Server.Transfer executes a new page and returns it's results to the browser but does not inform the browser that it returned a different page. So in such a case the browser url will show the original url requested but the contents will come from some other page. This is quite different than doing a Server.Redirect which will instruct the browser to request the new page. In such a case the url displayed in the browser will change to show the new url.

    To do the equivalent of a Server.Transfer in Asp.Net Core, you need to update the Request.Path and Request.QueryString properties to point to the url you want to transfer to and you need to instantiate the controller that handles that url and call it's action method. I have provided full code below to illustrate this.

    page1.html

     
        
            

    Page 1

    page2.html

     
        
            

    Page 2

    ExampleTransferController.cs

        using Microsoft.AspNetCore.Diagnostics;
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
    
        namespace App.Web.Controllers {
    
            public class ExampleTransferController: Controller {
    
                public ExampleTransferController() {
    
                }
    
                [Route("/example-transfer/page1")]
                public IActionResult Page1() {
                    bool condition = true;
    
                    if(condition) {
    
                        //Store the original url in the HttpContext items
                        //so that it's available to the app.
                        string originalUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}{HttpContext.Request.QueryString}";
                        HttpContext.Items.Add("OriginalUrl", originalUrl);
    
                        //Modify the request to indicate the url we want to transfer to
                        string newPath = "/example-transfer/page2";
                        string newQueryString = "";
                        HttpContext.Request.Path = newPath;
                        HttpContext.Request.QueryString = new QueryString(newQueryString);
    
                        //Now call the action method for that new url
                        //Note that instantiating the controller for the new action method
                        //isn't necessary if the action method is on the same controller as 
                        //the action method for the original request but
                        //I do it here just for illustration since often the action method you
                        //may want to call will be on a different controller.
                        var controller = new ExampleTransferController();
                        controller.ControllerContext = new ControllerContext(this.ControllerContext);
                        return controller.Page2();
                    }
    
                    return View();
                }
    
    
                [Route("/example-transfer/page2")]
                public IActionResult Page2() {
    
                    string originalUrl = HttpContext.Items["OriginalUrl"] as string;
                    bool requestWasTransfered = (originalUrl != null);
    
                    return View();
                }
    
            }
        }
    

    Placing the original url in HttpContext.Items["OriginalUrl"] isn't strictly necessary but doing so makes it easy for the end page to know if it's responding to a transfer and if so what the original url was.

提交回复
热议问题