Вопрос

Как я могу реализовать Post-Перенаправление-Получить шаблон с ASP.NET?

Нажатие кнопки выполняет некоторую обработку:

<asp:Button id="bbLaunch" OnCommand="bbLaunch_Click" />

Пользователь нажимает на кнопку, космический корабль запускается, веб-страница отображается повторно.Если пользователь нажимает клавишу F5, он получает предупреждение:

enter image description here

Решением этой проблемы является Post-Перенаправление-Получить закономерность.

Каков метод, с помощью которого PRG может быть реализован в ASP.NET?


Этот вопрос сосредоточен вокруг проблем:

  • как может <asp:Button> выполните POST в место, которое не является его первоначальным видом?
  • что становится с Состояние просмотра когда вы отправляете сообщение в форму, которая не читает состояние просмотра?
  • что становится с Состояние просмотра когда вы перенаправляетесь на "настоящую" веб-форму aspx?
  • является Состояние просмотра принципиально несовместим с ASP.net Опубликовать-Перенаправить-Получить?
  • является ASP.net принципиально несовместимым с Пост-Перенаправление-Получить?
  • как (т.е.какой код) вы перенаправляете на "настоящую" веб-форму aspx?
  • как (т.е.какой URL) вы перенаправляете на "настоящую" веб-форму aspx?В вопросе об отношении упоминается Response.Redirect(Request.RawUrl);
  • когда (т.е.в каком обработчике событий) вы перенаправляете на "настоящую" веб-форму aspx?
  • связанные с этим вопросы поднимают вопросы как вы публикуете данные формы.Подразумевается , что HTML формы не может быть использован - и все данные формы должны быть добавлены в строку запроса.Это правда?Если да, то почему?Если нет, то почему бы и нет? Может браузер помещает данные формы в строку запроса?
  • в связанном с этим вопросе упоминается Server.Transfer.Используя Server.Transfer является полностью неправильным и никоим образом не решает проблему получения после перенаправления (потому что нет Перенаправление).Правильно?
  • какое изменение кода должно произойти в aspx или aspx.cs файл для поддержки PRG?Предположительно, по крайней мере, код должен быть изменен на post где - то кроме MyPage.aspx.

Другими словами: Как вы делаете пост-редирект-Вход ASP.net?

Примечание:ASP.net (т.е.не ASP.net MVC)

Смотрите также

Это было полезно?

Решение

Как правило, вы делаете это, сделав веб -форму ASPX, которая использует запрос QueryString, чтобы сигнализировать, какая запись для загрузки/процесса.

Допустим, у вас есть страница, которая позволяет вам обновить некоторую информацию о клиентах:

http://www.mysite.com/customer.aspx

Вы бы загрузили форму, используя идентификатор в QueryString:

http://www.mysite.com/customer.aspx?CustomerId=42

В коде у вас будет что -то вроде этого:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        int customerId = 0;
        if (!string.IsNullOrEmpty(Request.QueryString["CustomerId"]))
        {
            int.TryParse(Request.QueryString["CustomerId"], out customerId );
        }
        if (customerId == 0) 
        {
            //handle case when no valid customer id was passed in the qs here
        }
        else 
        {
            //load customer details, bind controls etc
            //make sure to handle the case when no customer was found using the id in the qs
        }
    }
}

Тогда где -то на вашей странице у вас будет кнопка, которая сохраняет изменения. Эта кнопка будет иметь обработчика OnClick в коде:

protected void SaveClicked(object sender, EventArgs e)
{
    //save changes to database here

    //Redirect if all went well
    Response.Redirect("http://www.mysite.com/customer.aspx?CustomerId=" 
        + idOfSavedCustomer.ToString());
}

Это должно быть в основном. Перенаправление приведет к тому, что браузер выпустит новый запрос на получение URL -адреса в перенаправлении (...). Он загрузит страницу, if (!IsPostBack) Запустит и инициализирует страницу с помощью новых значений, которые вы только что сохранили в предыдущем посте обратно.

Для всего этого процесса трафик между браузером и сервером будет выглядеть примерно так:

Browser: GET http://www.mysite.com/customer.aspx?CustomerId=42
Server: 200 (send back some html)

Browser: POST http://www.mysite.com/customer.aspx?CustomerId=42 (post data sent in request)
Server: 302 (point to http://www.mysite.com/customer.aspx?CustomerId=42)

Browser: GET http://www.mysite.com/customer.aspx?CustomerId=42
Server: 200 (send html)

На среднем этапе сервер в основном говорит:

«Это сообщение о том, что вы мне прислали, я закончил с этим. Теперь, пожалуйста, добрались до этой другой страницы здесь ...»

Тот факт, что URL фактически направляется на одну и ту же страницу, не важен.


Некоторые размышления в ответ на список вопросов вашего пули:

  • Как можно выполнить пост в место, которое не является его оригинальной формой?

Вы можете сделать это, установив action атрибут в форме, или вы можете установить PostBackUrl на кнопке.

  • Что становится с ViewState, когда вы публикуете форму, которая не читает состояние просмотра?

Зависит от. Если вы просто опубликуете форму на другую страницу, вы можете использовать директиву <%@ предыдущий PageType .../>, чтобы рассказать страницу «Новая», откуда пришла пост. Это просто будет работать с опубликованными данными на новой странице. Видеть Эта ссылка для деталей.

  • Что становится с ViewState, когда вы перенаправляете в «настоящую» веб -форму ASPX?

Государство просмотра отправляется в запросе POST. При перенаправлении браузер загрузит новую страницу, и он создаст свой собственный Viestate.

  • Является ли ViewState принципиально несовместима с ASP.NET Post-RED-RECE-GET?

Зависит от того, как ты смотришь на это. После перенаправления новая страница не будет иметь доступа к ViewState страницы.

  • ASP.NET принципиально несовместима с пост-переездом-Get?

Нет. См. Пример выше.

  • Как (т.е. какой код) вы перенаправляете в «настоящую» веб -форму ASPX?

Ответ. Redirect (URL). Это отправит ответ в браузер, заявив, что он выполнит новый запрос на получение.

  • Когда (т.е. в каком обработке событий) вы перенаправляете в «настоящую» веб -форму ASPX?

Когда вы выполнили всю работу, необходимую для обработки запроса POST.

  • Связанные вопросы поднимают вопросы о том, как вы публикуете данные формы. Существует значение, что HTML -формы нельзя использовать - и все данные формы должны быть добавлены в строку запроса. Это правда? Если так, почему? Если нет, то почему бы и нет? Может ли браузер поместить данные формы в строку запроса?

Перенаправление запроса почты не очень хорошо поддерживается и, вероятно, следует избегать. Это можно сделать (с некоторым браузером) с помощью HTTP -ответа 307. При этом сервер эффективно сообщает браузеру, что », что», что »Я не буду обрабатывать вас публиковать запрос, пожалуйста, опубликуйте его на другую страницу вместо этого".

  • Связанный вопрос упоминает Server.transfer. Использование Server.Transfer совершенно неверно и никоим образом не решает проблему после переезда (потому что нет перенаправления). Правильный?

Server.Transfer (...) - это то, что происходит на стороне сервера. Браузер не знает об этом. По сути, страница может использовать Server.transfer для того, чтобы что -то другая страница сделала некоторую обработку, и эта страница будет отвечать за отправку ответа обратно в браузер. Но браузер подумает, что это была оригинальная страница, на которую ответил.

  • Какое изменение кода должно произойти в файле aspx или aspx.cs для поддержки PRG? Предположительно, по крайней мере, код должен быть изменен, чтобы опубликовать где -нибудь, кроме mypage.aspx.

Нет, можно использовать обычный пост. Хитрость состоит в том, чтобы иметь один (или несколько) конкретных обработчиков событий на странице, который выполняет repsonse.redirect после обработки размещенных данных.

Другие советы

Q) Как можно выполнить пост в место, которое не является его первоначальной формой?

А) С помощью PRG вы не публикуете на другую страницу, вы отправляете обратно на одну и ту же страницу (см. Диаграмму на странице Википедии, на которой вы связаны.) Но ответ с этой страницы должен быть 30 -кратным ответом (обычно 302 ..

Q) Что становится с ViewState, когда вы публикуете форму, которая не читает состояние просмотра?

А) Государство просмотра есть, когда вы публикуете, но состояние представления не будет для новой страницы, которую вы делаете.

Q) Что становится с ViewState, когда вы перенаправляете в «настоящую» веб -форму ASPX?

А) По вышеуказанную, больше нет состояния просмотра, перенаправляется на страницу.

Q) Является ли ViewState принципиально несовместима с ASP.NET?

А) ViewState не несовместима с ASP.NET. Он (в основном) бесполезен для P/R/G для рендеринга страницы, на которую вы перенаправлены.

Q) Является ли ASP.NET в корне несовместимо с пост-переездом-Get?

А) Нет - но вы не можете чрезмерно полагаться на использование одной страницы и сохранение всего вашего состояния в ViewState, как и выше. Тем не менее, asp.mvc намного лучше, чтобы P/r/g

Q) Как (т.е. какой код) вы перенаправляете в «настоящую» веб -форму ASPX?

A) response.redirect ("new_page_you_are_redirection_to.aspx") в методе bblaunch_click old_page_you_are_posting_from.aspx

Q) Как (т.е. какой URL) вы перенаправляете в «настоящую» веб -форму ASPX? Вопрос о отношениях упоминает ответ. Redirect (request.rawurl);

А) См. Выше

Q) Когда (т.е. в каком обработке событий) вы перенаправляете в «настоящую» веб -форму ASPX?

А) После того, как вы обработали кнопку, нажмите, сохранили данные в DB (или сеанс и т. Д.), И прежде чем вы записали что -нибудь еще в поток ответа.

Q) Связанные вопросы поднимают вопросы о том, как вы публикуете данные формы. Существует значение, что HTML -формы нельзя использовать - и все данные формы должны быть добавлены в строку запроса. Это правда?

А) Нет - кнопка нажимает в веб -формах ASP.NET, отправляется обратно на страницу.

Q) Если да, то почему? Если нет, то почему бы и нет?

А) Это проще этого, почему бы и нет. Визуализация двух страниц: first_page.asp и second_page.aspx. First_page.aspx имеет кнопку на ней (наряду с другими веб -элементами ASP.NET, например, текстовыми полями и т. Д., что пользователь заполнил.) Когда они нажимают кнопку, пост сделан на first_page.aspx. После обработки данных (которые, вероятно, находятся внутри ViewState, хотя это абстрагировано), вы перенаправляете пользователя на Second_Page.aspx с помощью response.redirect. Second_page.aspx может отображать то, что вы хотите. Если вы хотите (или нужно) отобразить пользовательский интерфейс, аналогичный тому, что было на first_page.aspx, включая элементы управления и то, что они вводя Эти элементы управления на second_page.aspx. (Но вам, возможно, не нужно будет отображать что -либо на second_page.aspx, что похоже на first_page.aspx - поэтому здесь нет общего правила.)

Q) Может ли браузер поместить данные формы в строку запроса?

А) Да, если вы установите метод, чтобы получить вместо поста. Вы не можете переопределить WebForms, чтобы сделать это, и это не требуется для PRG

Q) Связанный вопрос упоминает Server.transfer. Использование Server.Transfer совершенно неверно и никоим образом не решает проблему после переезда (потому что нет перенаправления). Правильный?

А) по существу

Q) Какое изменение кода должно произойти в файле ASPX или ASPX.CS для поддержки PRG? Предположительно, по крайней мере, код должен быть изменен, чтобы опубликовать где -нибудь, кроме mypage.aspx.

А) Код все еще должен опубликовать обратно (как упомянуто выше.) Но затем mypage.aspx должен повторно направить на новую страницу в обработке кнопок.

Паттерн после Redlect-Get можно использовать в веб-формах. Я показал, как это можно сделать, преобразовав приложение MVC Nerddinner в веб -формы, http://navigationnerddinner.codeplex.com/ Анкет Я сохранил навигационные детали точно одинаково, поэтому есть множество примеров схемы PRG.

Тем не менее, есть еще один способ избежать проблемы F5/обновления. Если вы оберните свою страницу в PartyPanel (часть ASP.NET AJAX), то все обратные сообщения будут преобразованы в запросы на частичную страницу. Это означает, что когда F5 нажимается, он только обновит исходный запрос GET (поскольку не было никаких последующих сообщений), и поэтому вы не получите предупреждение. (Обратите внимание, что если JavaScript отключен, предупреждение все равно будет появляться).

Точные шаги Post перенаправления получите это:

У вас есть форма, которую вы выполняете с данными, и после вашего действительного отправки (post) вы вставляете их в свою базу данных и предоставляете им идентификатор подтверждения, затем перенаправляете пользователя на страницу с помощью этого идентификатора подтверждения в качестве параметра URL, который используется Поскольку (get) после перенаправления, каждый F5-рефреш читает только данные и не вставляйте их снова.

Код для вставки отличается от кода, который показывает подтверждение, вы даже можете сделать их разными страницами - вы можете сделать одну и ту же страницу с текстовыми полями только для чтения.

Перенаправление прост Responce.Redirect Функция ASP.NET

После поста и создания перенаправления единственное, что подключение вас к предыдущему действию - это код подтверждения (не ViewState)

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

Альтернатива состоит в том, чтобы распознать обновление, а не сделать перенаправление. Признайте обновление на пост обратно, вы можете избежать вставки одних и тех же данных с одним сообщением пользователю. В Интернете есть несколько примеров, и я внедрил один с успехом.

Один пример: http://www.codeproject.com/tips/319955/how-to-prevent-re-post-action-caused-by-pressing-b

Вы можете вызвать Response.redirect метод перейти в другое место.

Есть пара вещей, которые имеют к этому отношение.

  1. Установите Экшен атрибут формы на главной странице (назовем его Форма запуска.aspx) равен URL страницы "прокси" (ProxyLaunchForm.aspx).

    <form id="form1" runat="server" action="ProxyLaunchForm.aspx" method="POST">

  2. (необязательно) Добавьте скрытый ввод с именем Перенаправление к форме и укажите URL-адрес, который сообщает ProxyLaunchForm.aspx куда перенаправить после завершения выполнения запуска (R-часть PRG).

  3. Теперь по ProxyLaunchForm.aspx, реализация должна происходить внутри Страница_загрузки обработчик событий, потому что у него есть доступ к данным form post.Выполните запуск здесь.

  4. Впоследствии (также в Страница_загрузки), выполните перенаправление (либо используя Перенаправление из # 2 или просто используя URL ссылающейся страницы):

    Ответ.Перенаправление(Запрос.Параметры["redirectUrl"]??Запрос.UrlReferrer.absoluteURI);

    Все еще остается вопрос о состоянии просмотра.Я думаю, что самый простой способ справиться с этим - изменить способ сохранения состояния просмотра.Обычно он сохраняется в скрытом элементе ввода на странице и извлекается при обратной передаче (что, конечно, означает, что он будет потерян после перенаправления из-за отсутствия состояния HTTP).Однако вы можете переопределить методы, которые использует ASP.net, и заставить его использовать Сессия вместо этого (таким образом, он все еще будет присутствовать даже после действия прокси-сервера PRG).Итак, наконец-то...

  5. В LaunchForm.aspx.cs, использовать в качестве базового класса подкласс Страница это переопределяет Сохранить страницу statetopersistencemedium и Loadpagestate из среды сохранения методы для сохранения / извлечения их из сеанса, а не из скрытого поля формы.Смотрите ниже (и вот более подробная информация о том, как это работает.).

*

public class PersistViewStateToSession : Page
{
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
        // serialize the view state into a base-64 encoded string
        LosFormatter los = new LosFormatter();
        StringWriter writer = new StringWriter();
        los.Serialize(writer, viewState);
        // save the string to session
        Session["LaunchViewState"] = writer.ToString();
    }

    protected override object LoadPageStateFromPersistenceMedium()
    {
       if (!Session["LaunchViewState"] == null)
           return null;
       else
       {
          string sessionString = (string)Session["LaunchViewState"];
          // deserialize the string
          LosFormatter los = new LosFormatter();
          return los.Deserialize(viewStateString);
       }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top