Post-Перенаправление-Получить с помощью ASP.NET
-
28-10-2019 - |
Вопрос
Как я могу реализовать Post-Перенаправление-Получить шаблон с ASP.NET?
Нажатие кнопки выполняет некоторую обработку:
<asp:Button id="bbLaunch" OnCommand="bbLaunch_Click" />
Пользователь нажимает на кнопку, космический корабль запускается, веб-страница отображается повторно.Если пользователь нажимает клавишу F5, он получает предупреждение:
Решением этой проблемы является 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 метод перейти в другое место.
Есть пара вещей, которые имеют к этому отношение.
Установите Экшен атрибут формы на главной странице (назовем его Форма запуска.aspx) равен URL страницы "прокси" (ProxyLaunchForm.aspx).
<form id="form1" runat="server" action="ProxyLaunchForm.aspx" method="POST">
(необязательно) Добавьте скрытый ввод с именем Перенаправление к форме и укажите URL-адрес, который сообщает ProxyLaunchForm.aspx куда перенаправить после завершения выполнения запуска (R-часть PRG).
Теперь по ProxyLaunchForm.aspx, реализация должна происходить внутри Страница_загрузки обработчик событий, потому что у него есть доступ к данным form post.Выполните запуск здесь.
Впоследствии (также в Страница_загрузки), выполните перенаправление (либо используя Перенаправление из # 2 или просто используя URL ссылающейся страницы):
Ответ.Перенаправление(Запрос.Параметры["redirectUrl"]??Запрос.UrlReferrer.absoluteURI);
Все еще остается вопрос о состоянии просмотра.Я думаю, что самый простой способ справиться с этим - изменить способ сохранения состояния просмотра.Обычно он сохраняется в скрытом элементе ввода на странице и извлекается при обратной передаче (что, конечно, означает, что он будет потерян после перенаправления из-за отсутствия состояния HTTP).Однако вы можете переопределить методы, которые использует ASP.net, и заставить его использовать Сессия вместо этого (таким образом, он все еще будет присутствовать даже после действия прокси-сервера PRG).Итак, наконец-то...
В 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);
}
}
}