Вы верны. Server.Transfer и Server.Redirect сильно отличаются. Server.Transfer выполняет новую страницу и возвращает результаты в браузер, но не сообщает браузеру, что он возвратил другую страницу. Таким образом, в таком случае URL-адрес браузера отобразит оригинальный URL-адрес, но содержимое будет получено с какой-либо другой страницы. Это совсем не так, как для Server.Redirect, который будет запрашивать браузер для запроса новой страницы. В этом случае URL-адрес, отображаемый в браузере, изменится, чтобы отобразить новый URL-адрес.
Чтобы сделать эквивалент Server.Transfer в Asp.Net Ядра, вам нужно обновить Request.Path
и Request.QueryString
свойства, чтобы указать URL-адрес, который требуется передать, и вам необходимо создать экземпляр контроллера, который обрабатывает, что URL-адрес и вызовите его метод действия. Я привел полный код ниже, чтобы проиллюстрировать это.
page1.html
<html>
<body>
<h1>Page 1</h1>
</body>
</html>
page2.html
<html>
<body>
<h1>Page 2</h1>
</body>
</html>
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();
}
}
}
Размещение оригинального URL-адреса в HttpContext.Items["OriginalUrl"]
не является абсолютно необходимым, но при этом конечная страница позволяет легко узнать, отвечает ли он на перевод, и если да, то каким был оригинальный URL-адрес.
Возможный дубликат [Перенаправление в asp.net 5] (http://stackoverflow.com/questions/30429350/redirecting-in-asp-net-5) –
Я собирал все параметры, а затем выполнял команду «Переадресация» или «RedirectToAction», как показано [в этом ответе] (http://stackoverflow.com/a/30430848/97471) –
@GerardoGrignoli Я хотел сохранить такое же поведение. То есть выполнение изменений на стороне сервера, чтобы клиент не выполнял никакой работы и не знал, что он перенаправлен на другую страницу. [Server.Transfer vs Response.Redirect] (http://stackoverflow.com/questions/224569/server-transfer-vs-response-redirect) –