重定向后 - 使用ASP.NET获取

Ian*_*oyd 41 asp.net redirect-after-post post-redirect-get

如何使用ASP.NET 实现Post-Redirect-Get模式?

按钮单击执行一些处理:

<asp:Button id="bbLaunch" OnCommand="bbLaunch_Click" />
Run Code Online (Sandbox Code Playgroud)

用户点击按钮,启动航天器,重新显示网页.如果用户按下F5,他们会收到警告:

在此输入图像描述

该问题的解决方案是Post-Redirect-Get模式.

PRG可以在ASP.NET中实现的方法是什么?


问题围绕以下问题:

  • 如何<asp:Button>执行一个POST不是原始形式的地方?
  • 当您发布到不读取视图状态的表单时,ViewState会变成什么?
  • 当您重定向到"真正的"aspx Web表单时,ViewState会变成什么?
  • 的ViewState与根本不相容的ASP.net后重定向消息得到什么?
  • ASP.net从根本上与Post-Redirect不兼容- Get
  • 你如何(即什么代码)重定向到"真正的"aspx Web表单?
  • 如何(即什么网址)你重定向到"真正的"aspx网页表单?关系问题提到Response.Redirect(Request.RawUrl);
  • 什么时候(即在什么事件处理程序中)你重定向到"真正的"aspx Web表单?
  • 相关问题引发如何发布表单数据的问题.这意味着无法使用HTML 表单 - 并且必须将所有表单数据添加到查询字符串中.这是真的?如果是这样,为什么?如果没有,为什么不呢?可以在浏览器把表单数据的查询字符串?
  • 一个相关的问题提到Server.Transfer.使用Server.Transfer是完全错误的,决不会解决Post-Redirect-Get问题(因为没有重定向).正确?
  • 在支持PRG的文件aspxaspx.cs文件中必须进行哪些代码更改?据推测,至少,代码必须改为post其他地方MyPage.aspx.

换句话说:你如何在ASP.net中进行重定向后获取?

注意:ASP.net(即不是ASP.net MVC)

也可以看看

use*_*080 36

通常,您可以通过创建一个aspx Web表单来执行此操作,该表单使用查询字符串来指示要加载/处理的记录.

假设您有一个页面让您更新一些客户信息:

http://www.mysite.com/customer.aspx
Run Code Online (Sandbox Code Playgroud)

您将使用查询字符串中的id加载表单:

http://www.mysite.com/customer.aspx?CustomerId=42
Run Code Online (Sandbox Code Playgroud)

在代码隐藏中你会有这样的事情:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在页面的某个位置,您将有一个保存更改的按钮.该按钮在后面的代码中有一个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());
}
Run Code Online (Sandbox Code Playgroud)

基本上应该是它.重定向将导致浏览器在重定向(...)中为URL发出新的GET请求.它将加载页面,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)
Run Code Online (Sandbox Code Playgroud)

在中间步骤,服务器基本上说:

"你发给我的那个帖子请求,我已经完成了.现在请到这里的其他页面......"

实际上url指向同一页面的事实并不重要.


一些想法回应你的问题点列表:

  • 如何对不是原始形式的地方执行POST?

您可以通过action在表单上设置属性来执行此操作,也可以PostBackUrl在按钮上进行设置.

  • 当您发布到不读取视图状态的表单时,ViewState会变成什么?

要看.如果您只是将表单发布到其他页面,则可以使用<%@ PreviousPageType ... />指令来指示帖子来自的"新"页面.这将简单地使用新页面上的发布数据.请参阅此链接了解详情.

  • 当您重定向到"真正的"aspx Web表单时,ViewState会变成什么?

视图状态在发布请求中发送.重定向时,浏览器将加载一个新页面,它将创建自己的viestate.

  • ViewState是否与ASP.net Post-Redirect-Get根本不兼容?

取决于你如何看待它.重定向后,新页面将无法访问之前页面的视图状态.

  • ASP.net从根本上与Post-Redirect不兼容 - Get?

不.见上面的例子.

  • 你如何(即什么代码)重定向到"真正的"aspx Web表单?

Response.Redirect的(URL).这将向浏览器发送响应,告诉它执行新的get请求.

  • 什么时候(即在什么事件处理程序中)你重定向到"真正的"aspx Web表单?

当您执行了处理发布请求所需的所有工作时.

  • 相关问题引发了您如何发布表单数据的问题.这意味着无法使用HTML表单 - 并且必须将所有表单数据添加到查询字符串中.这是真的?如果是这样,为什么?如果没有,为什么不呢?浏览器可以将表单数据放入查询字符串中吗?

重定向发布请求的支持不是很好,应该避免使用.可以通过使用http响应307来完成(使用某些浏览器).当这样做时,服务器有效地告诉浏览器" 我不会处理您发布请求,请将其发布到此其他页面 ".

  • 一个相关的问题提到Server.Transfer.使用Server.Transfer是完全错误的,并且决不会解决Post-Redirect-Get问题(因为没有重定向).正确?

Server.Transfer(...)是在服务器端发生的事情.浏览器不知道它.基本上,一个页面可以使用Server.Transfer,以便让其他页面执行某些处理,并且该页面将负责将响应发送回浏览器.但浏览器会认为这是响应的原始页面.

  • 在aspx或aspx.cs文件中必须进行哪些代码更改才能支持PRG?据推测,至少,代码必须更改为在MyPage.aspx之外的某处发布.

不,可以使用常规回发.诀窍是在页面上有一个(或几个)特定的事件处理程序,它们在处理发布的数据后执行Repsonse.Redirect.


小智 7

问)如何对不是原始形式的地方执行POST?

A)使用PRG,您不会POST到不同的页面,您回发到同一页面(请参阅您链接到的维基百科页面上的图表.)但该页面的响应必须是30X响应(通常为302) .)

Q)当您发布到不读取视图状态的表单时,ViewState会变成什么?

A)当您发布POST时,视图状态就在那里,但是您正在进行GET操作的新页面中不存在视图状态.

问)当您重定向到"真正的"aspx Web表单时,ViewState会变成什么样?

A)如上所述,没有更多的视图状态重定向到页面.

问)ViewState是否与ASP.net根本不兼容?

A)ViewState与ASP.NET不兼容.P/R/G(用于渲染您重定向到的页面)(大多数情况下)无用.

问)ASP.net与Post-Redirect根本不兼容 - Get?

A)否 - 但是您不能过度依赖使用一个页面并将所有状态保持在视图状态,如上所述.也就是说,ASP.MVC比P/R/G更好地映射

问)你如何(即什么代码)重定向到"真正的"aspx Web表单?

A)old_page_you_are_posting_from.aspx的bbLaunch_Click方法中的Response.Redirect("new_page_you_are_redirecting_to.aspx")

问)你如何(即什么网址)重定向到"真正的"aspx网络表单?关系问题提到Response.Redirect(Request.RawUrl);

A)见上文

Q)何时(即在什么事件处理程序中)您重定向到"真正的"aspx Web表单?

A)按下按钮后,将数据保存到DB(或会话等),然后再将其他任何内容写入Response流.

Q)相关问题引发了您如何发布表单数据的问题.这意味着无法使用HTML表单 - 并且必须将所有表单数据添加到查询字符串中.这是真的?

A)否 - ASP.NET WebForms中的按钮按下将POST回页面.

问)如果是这样,为什么?如果没有,为什么不呢?

A)比这更简单,为什么不呢.成像两页:first_page.asp和second_page.aspx.First_page.aspx上有按钮(以及用户填写的其他ASP.NET Web控件,如文本框等.)当他们按下按钮时,会对first_page.aspx进行POST.在处理完数据后(可能在viewstate中,尽管这是抽象的),您可以使用Response.redirect将用户重定向到second_page.aspx.Second_page.aspx可以显示您想要的内容.如果您希望(或需要)显示与first_page.aspx类似的UI,包括控件及其输入的内容,您可能希望将其存储在会话中,cookie,URL作为查询字符串参数,以设置second_page.aspx上的那些控件.(但你可能不需要在second_page.aspx上显示任何类似于first_page.aspx的内容 - 所以这里没有一般规则.)

问)浏览器可以将表单数据放入查询字符串吗?

A)是的,如果您将方法设置为GET而不是POST.您不能覆盖WebForms来执行此操作,PRG不需要这样做

Q)相关问题提到Server.Transfer.使用Server.Transfer是完全错误的,并且决不会解决Post-Redirect-Get问题(因为没有重定向).正确?

A)基本上

问)在aspx或aspx.cs文件中必须进行哪些代码更改才能支持PRG?据推测,至少,代码必须更改为在MyPage.aspx之外的某处发布.

A)代码仍然应该回发(如上所述.)但是Mypage.aspx应该重定向到按钮处理程序中的新页面.


Ari*_*tos 5

Post Redirect Get的确切步骤是这一步:

您拥有使用数据填写的表单,并在有效提交(POST)后将它们插入数据库,并为其提供确认ID,然后将用户重定向到具有此确认ID作为URL参数的页面作为(GET)重定向后,每个F5刷新只读取数据而不再插入它们.

插入代码与显示确认的代码不同,您甚至可以将它们设置为不同的页面 - 您可以使用只读文本框创建相同的页面.

重定向很简单Responce.Redirect,asp.net 的功能

在POST和重定向之后,唯一认为连接前一个操作的是确认代码(不是viewstate)

这种方法的减号,实际上是不承认的刷新,只是做一个额外的步骤,使该刷新不会再次插入相同的数据 - 但需要额外的代码,获取数据.

另一种方法是识别刷新而不是重定向.通过识别回发后的刷新,您可以避免将单个消息中的相同数据插入用户.互联网上有一些例子,我已经成功实施了一个.

一个例子:http://www.codeproject.com/Tips/319955/How-to-prevent-Re-Post-action-caused-by-pressing-b


gra*_*ick 5

Post-Redirect-Get模式可以在Web窗体中使用.我已经展示了如何通过将MVC NerdDinner应用程序转换为Web窗体,http: //navigationnerddinner.codeplex.com/来完成此操作.我保持导航细节完全相同,所以有很多PRG模式的例子.

但是,还有另一种方法可以避免F5/Refresh问题.如果将页面包装在UpdatePanel(ASP.NET Ajax的一部分)中,则所有回发都将转换为部分页面请求.这意味着当按下F5时,它只会刷新原始的GET请求(因为没有任何后续的POST),因此您不会收到警告.(注意,如果禁用JavaScript,则仍会显示警告).