2016-09-26 4 views
4

Я переношу приложение ASP.NET в ASP.NET Core, и у них есть несколько звонков на номер HttpServerUtility.Transfer(string path). Тем не менее, HttpServerUtility не существует в ASP.NET Core.Альтернатива Server.Transfer в ASP.NET Core

Есть ли альтернатива, которую я могу использовать? Или Response.Redirect единственный вариант, который у меня есть?

Я хочу как можно больше поддерживать прежнее поведение, поскольку существует разница между Server.Transfer and Response.Redirect.

+0

Возможный дубликат [Перенаправление в asp.net 5] (http://stackoverflow.com/questions/30429350/redirecting-in-asp-net-5) –

+0

Я собирал все параметры, а затем выполнял команду «Переадресация» или «RedirectToAction», как показано [в этом ответе] (http://stackoverflow.com/a/30430848/97471) –

+2

@GerardoGrignoli Я хотел сохранить такое же поведение. То есть выполнение изменений на стороне сервера, чтобы клиент не выполнял никакой работы и не знал, что он перенаправлен на другую страницу. [Server.Transfer vs Response.Redirect] (http://stackoverflow.com/questions/224569/server-transfer-vs-response-redirect) –

ответ

2

Я вижу несколько вариантов для вас, в зависимости от вашего случая:

  • Возвратившись другой вид: Так просто HTML. См. Ответ Muqeet Khan
  • Возврат другого метода того же контроллера: Это позволяет также выполнять бизнес-логику другого действия. Просто напишите что-нибудь вроде return MyOtherAction("foo", "bar").
  • Возврат действия другого контроллера: См. Ответ Рона К. Я немного в затруднении с этим решением, поскольку он опускает все промежуточное программное обеспечение, которое содержит 90% логики ядра ASP.NET (например, безопасность , куки, сжатие, ...).
  • Маршрутизация промежуточного программного обеспечения: Добавление промежуточного программного обеспечения, похожего на то, что делает маршрутизация. В этом случае ваша логика решения должна быть оценена там.
  • Позднее повторное использование стека промежуточного программного обеспечения: Вам необходимо повторно запустить большую часть стека. Я считаю, что это возможно, но пока не видел решения. Я видел презентацию Дамиана Эдвардса (PM для ядра ASP.NET), где он размещал ASP.NET Core без использования Kestrel/TCPIP только для визуализации HTML локально в браузере. Это можно сделать. Но это много перегрузки.

Слово совета: передача мертва;). Подобные различия являются причиной существования ASP.NET Core и повышения производительности. Это плохо для миграции, но это хорошо для всей платформы.

+0

Мое решение не запускает меньше промежуточного программного обеспечения, чем первые два решения, которые вы предлагаете, и почти наверняка использует больше промежуточного программного обеспечения, чем последнее два, которые вы предлагаете, чтобы вы вышли из промежуточного программного обеспечения, чтобы реализовать такое решение, если вы придумали код для него. И далее мое решение демонстрирует, как запускать логику действий для другого представления, обрабатываемого другим контроллером. –

+0

Это правда. Список, который я сделал, в основном показывает много разных способов, как может выглядеть Transfer. Я уверен, есть больше вариантов, учитывая гибкость ASP.NET Core. Ваше решение выглядит немного взломанным, однако я не читал подробностей о том, как промежуточное ПО MVC на самом деле это делает, поэтому он может быть на 100% легитимным. Я думаю, что самая важная часть моего ответа - это два последних абзаца;). – Thomas

+1

Server.Transfer в полной структуре выполняет код за страницей для передачи страницы и обслуживает эту страницу. Вероятно, есть и другие варианты, которые делают что-то аналогичное тому, что в ядре .net, кроме кода, который я создал, но я еще не видел, чтобы кто-либо подавал код для таких параметров. :-) –

0

Я считаю, что вы ищете возврат «named view» в MVC. Таким образом,

[HttpPost] 
public ActionResult Index(string Name) 
{ 
ViewBag.Message = "Some message"; 
//Like Server.Transfer() in Asp.Net WebForm 
return View("MyIndex"); 
} 

Вышеупомянутый вернет этот конкретный вид. Если у вас есть условие, которое регулирует детали просмотра, вы можете это сделать.

2

Вы верны. 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-адрес.

+0

Это может быть полезно только с кодом MVC (для запуска контроллера/представлений). Однако весь конвейер промежуточного программного обеспечения не будет выполнен, поэтому он не так хорош, как «Server.Transfer» –

+1

@ J.Lennon Server.Transfer также не выполняет повторный запуск полного конвейера. Я просто проверил его лично, и мои HttpModules никогда не были вызваны для новой страницы. –

+0

Это правда, конвейер (http-модули в старом asp.net) больше не будет выполнен. Проблема с вашим подходом заключается в том, что вы вызываете метод класса напрямую, игнорируя атрибуты, фильтры или любое поведение, которое может иметь контроллер. –

Смежные вопросы