Post-Redirect-получить с ASP.NET
как я могу использовать тег После Перенаправления-Get шаблон с ASP.NET?
нажатие кнопки выполняет некоторую обработку:
<asp:Button id="bbLaunch" OnCommand="bbLaunch_Click" />
пользователь нажимает кнопку, корабль запущен, веб-страницы открывает. Если пользователь нажимает F5, они получают предупреждение:
решение проблемы После Перенаправления-Get узор.
что такое метод PRG может быть реализован в ASP.NET?
вопрос сосредотачивается вокруг проблемы:
- как
<asp:Button>
выполнитьPOST
в место, которое не является его первоначальной формой? - что станет с ViewState когда вы отправляете сообщение в форму, которая не читает состояние просмотра?
- что станет с ViewState при перенаправлении на" реальный " aspx web форма?
- is ViewState принципиально несовместимы с
ASP.netПост-Редирект-Получить? - is ASP.net принципиально несовместимый с После Перенаправления--Get?
- как (т. е. какой код) вы перенаправляете в" реальную " веб-форму aspx?
-
как (т. е. какой url) вы перенаправляете в "реальную" веб-форму aspx? Вопрос отношения упоминает
Response.Redirect(Request.RawUrl);
- , когда (т. е. в каком обработчике событий) вы перенаправляете в "реальную" веб-форму aspx?
- связанные с этим вопросы поднимают вопросы как вы отправляете данные формы. Имеется в виду, что HTML формы невозможно использовать - и все данные формы должны быть добавлены в строку запроса. Это правда? Если так, то почему? Если нет, то почему? можете браузер данные из формы в строку запроса?
- соответствующий вопрос упоминания
Server.Transfer
. ИспользуяServer.Transfer
совершенно неправильно, и никоим образом не решает проблему Post-Redirect-Get (потому что нет редирект). Правильно? - какое изменение кода должно произойти в
aspx
илиaspx.cs
файл для поддержки PRG? Предположительно, по крайней мере, код должен быть изменен наpost
где-тоMyPage.aspx
.
другими словами: как Вы делаете Post-Redirect-Get in ASP.net?
Примечание: ASP.net (то есть нет ASP.net MVC)
см. также
6 ответов
обычно вы делаете это, делая веб-форму aspx, которая использует строку запроса, чтобы сигнализировать, какая запись загружается/обрабатывается.
предположим, у вас есть страница, которая позволяет вам обновлять некоторую информацию о клиентах:
http://www.mysite.com/customer.aspx
вы загрузите форму, используя идентификатор в строке запроса:
http://www.mysite.com/customer.aspx?CustomerId=42
в codebehind у вас будет что-то вроде этого:
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());
}
это должно быть в основном. Перенаправление приведет к тому, что браузер выдаст новый запрос GET для 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)
в середине шаг, сервер в основном говорит:
Q) Как выполнить сообщение в место, которое не является его первоначальной формой?
A) с PRG вы не публикуете на другой странице, вы публикуете обратно на ту же страницу (см. диаграмму на странице Википедии, с которой вы связаны.) Но ответ с этой страницы должен быть ответом 30X (обычно 302.)
Q) Что происходит с ViewState, когда вы отправляете в форму, которая не читает состояние представления?
A) состояние представления есть, когда вы публикуете, но есть состояние представления не будет там для новой страницы, которую вы делаете.
Q) Что происходит с ViewState при перенаправлении в "реальную" веб-форму aspx?
A) в выше, нет больше состояния просмотра перенаправление на страницу.
Q) является ViewState принципиально несовместимым с ASP.net?
A) ViewState не несовместим с ASP.NET - ... Это (в основном) бесполезно для P/R / G для рендеринга страницы, на которую вы перенаправлены.
Q) является ASP.net принципиально несовместимый с Post-Redirect -- Get?
A) нет-но вы не можете чрезмерно полагаться на использование одной страницы и сохранение всего вашего состояния в viewstate, как указано выше. Тем не менее, ASP.MVC-карты намного лучше P/R / G
Q) Как (т. е. какой код) вы перенаправляете в "реальную" веб-форму aspx?
A) Ответ.Redirect ("new_page_you_are_redirecting_to.aspx") в методе bblaunch_click метода old_page_you_are_posting_from.аспн
Q) Как (т. е. какой url) сделать вы перенаправляете на" реальную " веб-форму aspx? Вопрос отношения упоминает ответ.перенаправленный запрос.RawUrl);
A) см. выше
Q) когда (т. е. в каком обработчике событий) вы перенаправляете в "реальную" веб-форму aspx?
A) после обработки кнопки нажмите, сохраните данные в БД (или сеанс и т. д.), и прежде чем вы напишете что-либо еще в поток ответов.
Q) связанные вопросы поднимают вопросы о том, как вы публикуете данные формы. Есть подразумевается, что HTML-формы нельзя использовать - и все данные формы должны быть добавлены в строку запроса. Это правда?
A) нет - кнопка нажмите в ASP.NET WebForms отправит сообщение обратно на страницу.
Q), если да, то почему? Если нет, то почему?
A) это проще, чем это, почему бы и нет. Изображения двух страниц: first_page.asp и second_page.аспн. First_page.aspx имеет кнопку на нем (наряду с другими ASP.NET веб-элементы управления, такие как текстовые поля и т. д., которые пользователь заполнил.) Когда они нажимают кнопку, сообщение делается в first_page.аспн. После обработки данных (которые, вероятно, находятся внутри viewstate, хотя это абстрагировано), вы перенаправляете пользователя на second_page.aspx с помощью ответа.перенаправлять. Вторая полоса.aspx, который может отображать то, что вы хотите. Если вы хотите (или нужно), чтобы отобразить пользовательский интерфейс, который похож на то, что было на first_page.aspx, включая элементы управления и то, что они ввели, вы хотели бы сохранить это в сеансе, cookie, URL-адрес как параметры querystring, чтобы установить их контроль second_page.аспн. (Но вам может не понадобиться отображать что-либо на second_page.aspx, похожий на first_page.aspx-поэтому здесь нет общего правила.)
Q) может ли браузер поместить данные формы в строку запроса?
A) да, если вы установите метод GET вместо POST. Вы не можете переопределить WebForms для этого, и это не требуется для PRG
Q) связанный вопрос упоминает сервер.Передача. Использование Сервера.Перевод совершенно неправильный, и ни в коем случае решает проблему Post-Redirect-Get (потому что нет перенаправления). Правильно?
A) По Существу
Q) какое изменение кода должно произойти в aspx или aspx.cs файл для поддержки PRG? Предположительно, по крайней мере, код должен быть изменен на post где-то кроме MyPage.аспн.
A) код должен по-прежнему возвращаться (как упоминалось выше.) Но тогда Mypage.aspx должен перенаправить на новую страницу в обработчике кнопок.
точные шаги Post Redirect Get - это:
http://www.planethost.gr/PostRedirectGet.jpg
у вас есть форма, которую вы заполняете данными, и после вашей действительной отправки (POST) вы вставляете их в свою базу данных и даете им идентификатор подтверждения, затем вы перенаправляете пользователя на страницу с этим идентификатором подтверждения в качестве параметра URL, который используется как (GET) после перенаправления каждый F5-refresh только считывает данные и не вставляет их снова.
код для вставки отличается от кода, который показывает подтверждение, вы даже можете сделать их разными страницами - вы можете сделать ту же страницу с текстовыми полями только для чтения.
перенаправление просто Responce.Redirect
функция asp.net
после публикации и создания перенаправления единственное, что вас связывает с предыдущим действием, - это код подтверждения (а не viewstate)
минус этого метода заключается в том, что на самом деле является не распознайте обновление, просто сделайте дополнительный шаг, который сделает обновление не вставляя снова те же данные, но нуждается в дополнительном коде для получения данных.
альтернативой является распознавание обновления и не перенаправление. Распознав обновление на post back, вы можете избежать вставки одних и тех же данных с одним сообщением пользователю. Для этого есть несколько примеров в интернете, и я успешно реализовал один из них.
Один Пример: http://www.codeproject.com/Tips/319955/How-to-prevent-Re-Post-action-caused-by-pressing-b
шаблон Post-Redirect-Get можно использовать в веб-формах. Я показал, как это можно сделать, преобразовав приложение MVC NerdDinner в веб-формы,http://navigationnerddinner.codeplex.com/ . Я сохранил детали навигации точно так же, поэтому есть много примеров шаблона PRG.
однако есть еще один способ избежать проблемы F5 / Refresh. Если вы обернете свою страницу в UpdatePanel (часть ASP.NET Ajax), то все почтовые спины будут преобразуется в частичные запросы страниц. Это означает, что при нажатии F5 он обновит только исходный запрос GET (поскольку не было никаких последующих сообщений), и поэтому вы не получите предупреждение. (Обратите внимание, что если JavaScript отключен, предупреждение все равно появится).
есть несколько вещей, которые входят в этот.
-
установить действие атрибут формы на главной странице (назовем его LaunchForm.аспн), равный URL-адресу страницы "прокси" (ProxyLaunchForm.аспн).
(опционально) добавить скрытый input с именем параметр redirecturl к форме и значению URL, который сообщает ProxyLaunchForm.аспн где перенаправить, как только он закончит выполнение запуска (R часть PRG).
теперь о ProxyLaunchForm.аспн реализация должна происходить внутри в обработчик событий, потому что он имеет доступ к данным формы post. Запуск здесь.
-
затем (также в в), перенаправление (либо с помощью параметр redirecturl из #2, или просто с помощью ссылки URL страницы):
ответ.перенаправленный запрос.Params ["redirectUrl"]?? Запрос.UrlReferrer.AbsoluteUri);
остается вопрос о состоянии представления. Я думаю, что самый простой способ справиться с этим-изменить то, как сохраняется состояние представления. Обычно он сохраняется в скрытом элементе ввода на странице и извлекается при обратной передаче (что, конечно, означает, что он будет потерян после перенаправления из-за безгосударственного характера HTTP). Однако можно переопределить методы, которые ASP.net использует, и пусть он использует сессии вместо этого (таким образом, он все равно будет присутствовать даже после действия прокси-сервера PRG). Ну, наконец-то...
на LaunchForm.аспн.cs, используйте в качестве базового класса подкласс страница, который переопределяет SavePageStateToPersistenceMedium и LoadPageStateFromPersistenceMedium методы для сохранения/извлечения их из сеанса, а не из скрытого поля формы. См. ниже (и вот еще информация о том, как это работает.).
*
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);
}
}
}