asp.net如何记住网页之间的变量值
Posted
技术标签:
【中文标题】asp.net如何记住网页之间的变量值【英文标题】:How to remember variable value between web pages asp.net 【发布时间】:2021-11-18 15:38:06 【问题描述】:我正在构建一个应用程序,可以为特定工作聘请顾问(候选人)。在索引页面的一个表格中,加载了随机候选人的个人资料。 在页面加载时: html:
<table class="table-random-candidate">
<asp:Label ID="LblIdCandidate" runat="server" ></asp:Label>
<asp:Button ID="BtnLearnMore" runat="server" Text="Learn More"
OnClick="BtnLearnMore_Click" />
</table>
在代码隐藏中:
Sqlquery=”SELECT TOP 1 IdCandidate, ”
“ORDER BY NEWID”;
con.Open();
SqlCommand cmd = new SqlCommand(sqlquery, con);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
IdCandidateRemember=reader[“IdCandidate”].ToString();
LblIdCandidate.Text= IdCandidateRemember;
候选人的信息加载正确。 这就是问题所在:我希望用户单击候选人表格中的一个按钮,该按钮会将用户发送到候选人的详细信息页面:
protected void BtnLearnMore_Click(object sender, EventArgs e)
Response.Redirect("Candidate_Details.aspx?Id=" +
IdCandidateRemember);
问题在于,在 BtnLearnMore_Click 上,加载了另一个候选者的页面,我假设它是下一个随机选择的候选者。也就是说,网页不记得要记住的 IdCandidateRemember。我尝试过使用 Session 和 QueryString,但没有成功,这可能只是表明我并不真正了解它们是如何工作的。 当我在 HTML 中使用 DataList 和以下按钮时,pagecall 工作正常:
<asp:Button ID="BtnLearnMore" runat="server" Text="Learn More"
PostBackUrl='<%#"Candidate_Details.aspx?id="+Eval("IdCandidate")%>'
/>
但是对于这张桌子,我特别需要使用阅读器 任何帮助将不胜感激!
【问题讨论】:
不是一个真正的编码问题,更多的设计/架构,弄清楚你的页面应该做什么和不做什么。加载用户——当你真的想告诉页面加载哪个用户时——似乎是个问题。您可能需要一个全新的页面来显示用户详细信息。 感谢您的回复。详情页是; Candidate_Details.aspx,效果很好。所有候选人都使用相同的页面格式,并且为每个候选人加载相应的候选人详细信息。当使用以下方法调用它时: PostBackUrl='' 它工作得很好。我的问题是我不知道如何使用阅读器将 IdCandidate 发送到详细信息页面,而不是使用 DataList。 我认为这个问题之前已经被问过了,如果不是在这里,那么在网络上。由于连接关闭,这并不是真正简单的 IIRC,还是正确的?我可能是错的。您可能需要另一种方法,但我确信我已经看过有关它的帖子或文章。为了在这里获得更好的帮助,您应该编辑您的问题并摆脱所有额外的东西。使用您最后评论的最后一句话作为您的问题的基础,然后摆脱其余部分。 【参考方案1】:在这部分你可以使用的代码:
if (reader.Read())
IdCandidateRemember=reader[“IdCandidate”].ToString();
Session["IdCandidateRemeber"] = IdCandidateRemember;
LblIdCandidate.Text= IdCandidateRemember;
只要会话持续时间,IdCandidateRemeber 就保存在 Session 变量中,请注意在使用完毕时处理变量
然后在你的底部你可以使用
protected void BtnLearnMore_Click(object sender, EventArgs e)
Response.Redirect("Candidate_Details.aspx?Id=" +
Convert.ToString(Session["IdCandidateRemember"]));
如果你打算只在一个页面中使用,你可以使用 ViewState 而不是 Session
【讨论】:
对于我的回复延迟表示歉意。我终于让这个工作了。你的建议奏效了。我无法让它工作很长时间,因为我在加载候选人之前未能添加 if (!IsPostBack)。真是个愚蠢的错误!感谢您的帮助。【参考方案2】:好的,所以这是标准的公平。您有一个应用程序,用户可能会说搜索酒店或其他任何内容。你显示一个网格。
用户选择一个值。现在是时候计算出那个客户、那个项目、那个订单或者其他什么的细节了。平面简数据库的东西 - 每天都做。
那么,虽然网络概念是无状态的? (与桌面不同,您的代码值保持不变?
在网络领域,每个页面都回传,您的代码每次都从头开始!
因此,在每个 Web 请求上都会创建一个页面类的“新”实例。 (除非您对 Web 方法使用 ajax 调用 - 但是当您这样做时,您的代码不能触摸也不能查看任何控件值 - 因为在该页面回发发生之前它们不存在。
好的,那么你现在的设计模式是什么?
毕竟,就像任何应用程序一样,您可以单击一行,然后显示详细信息或跳转到另一个页面以说编辑该选择。
这里有几种方法。
首先,还是很常见?
您在 url 中传递值。事实上,在输入这篇文章时,我可以在 URL 中看到堆栈溢出代码使用的“消息”编号(值)。
你仍然会看到亚马逊或其他服务的网址中经常有很多“东西”。
www.mywebsite.com?&ID=134&Account=5454444
因此,您可以使用 URL 参数(通常称为查询字符串值)将值传递给下一个 Web 表单购买。现在这种方法的问题是什么?好吧,对于某些东西,比如数据库 PK 值,甚至是信用卡号?您不希望该信息暴露给用户。更糟糕的是,用户可以“乱用”并修改这些值。
现在,对于一般网站,假设我们想要一个城市的人口? www.mywebsite.com/ShowPopulation.aspx?City="New约克"
在上面,效果很好,因为最终用户甚至可以更改该值。
而且一些大型网站仍然使用这种方法,因为它在服务器端的成本为零(因此为了获得巨大的可扩展性,这种选择是可行的)。
但是,今天,我们有了更好的选择,我非常不喜欢那些乱七八糟的 URL。它们可能会带来安全问题。
因此,您可以将行点击“ID”传递给 URL 中的下一个表单。
下一个?
视图状态:
ViewState 是每页的。并且不会暴露于 URL。因此这是一个很好的选择,我将结合为什么这个选择通常比下一个选择好得多。
会话: 嗯,这个真的很漂亮。它允许您将变量推入 session(),并且它们在应用程序范围内保持每个用户!!!
但是,你要小心使用 session() 而不加考虑!!!
假设我们有一个您要预订的酒店网格。
因此,您可以使用 session() 将此酒店“ID”传递给下一个表单。
但是,如果同一用户启动另一个浏览器页面并选择了不同的酒店,然后跳转到酒店预订页面,会发生什么情况。如果我们将酒店 ID 存储在 session() 中?
该用户的应用范围很广!!!因此,现在在酒店预订中打开了两个网页,我们将在会话中获得错误的 pk id。如果你说要买房呢?那么要么你不允许一个用户打开一个以上的购房页面,要么你只使用会话来传递值。
所以,我所做的是使用 session() 将值传递给下一个表单,然后立即将传递的值移动到 ViewState。 (因为视图状态是每页)。
所以,让我们填充一个网格,从网格中选择一家酒店,然后跳转到下一页。
所以说我们有这个:
<div style="width:50%;margin-left:25px;margin-top:25px">
<asp:GridView ID="MyGrid" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false" OnRowDataBound="MyGrid_RowDataBound" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Province" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:CheckBoxField DataField="Active" HeaderText="Active" ItemStyle-HorizontalAlign="Center" />
<asp:TemplateField >
<ItemTemplate>
<asp:Button ID="cmdHotelSel" runat="server" Text="View Hotel"
OnClick="cmdHotelSel_Click"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
我们在代码中加载网格:
protected void Page_Load(object sender, EventArgs e)
if (IsPostBack == false)
LoadGrid();
public void LoadGrid()
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotels ORDER by HotelName ",
new SqlConnection(Properties.Settings.Default.TEST3)))
cmdSQL.Connection.Open();
MyGrid.DataSource = cmdSQL.ExecuteReader();
MyGrid.DataBind();
好的,我们现在有了这个:
好的,让我们使用 Session 将行点击传递到下一页 (比如显示酒店信息的详细信息表格)。
所以,按钮点击代码可以是这个(获取PK行id)
protected void cmdHotelSel_Click(object sender, EventArgs e)
Button btn = (Button)sender;
GridViewRow gRow = (GridViewRow)btn.Parent.Parent;
int PK = (int)MyGrid.DataKeys[gRow.RowIndex]["ID"];
Session["HotelPK"] = PK;
Response.Redirect("ViewHotel.aspx");
所以,我们将 PK id 推入 session()。 (会话 = 全局 = 每个用户)
所以,现在在目标页面上,我们可以这样做:
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
if (Session["HotelPK"] == null)
// no value - lets jump to View Hotels page
Response.Redirect("GridRowSel.aspx");
else
ViewState["HotelPK"] = Session["HotelPK"];
ShowHotelInfo();
void ShowHotelInfo()
// code here to load Hotel information from ViewState[HotelPK]
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotels WHERE ID = @ID" ,
new SqlConnection(Properties.Settings.Default.TEST3)))
cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = ViewState["HotelPK"];
cmdSQL.Connection.Open();
Repeater1.DataSource = cmdSQL.ExecuteReader();
Repeater1.DataBind();
所以在上面,我们使用中继器控件来呈现一个酒店记录。
所以使用 session() 传递值的“规则”是可以的,但请注意我做的第一件事是将会话转移到 ViewState。我这样做是因为用户可以右键单击,甚至启动另一个浏览器。因此,如果有两家酒店营业,那么两个页面都可以正常运行,我不在乎会话值是否发生了变化。
另一种坚持的方法?
我们经常在网页上使用控件——甚至是隐藏的控件。这通常很方便,因为客户端 JS 代码也可以在页面上使用此类值。
所以,这应该会给你一些想法。
【讨论】:
就像我对奥斯卡说的:抱歉我的回复延迟。我终于让这个工作了。你的建议奏效了。我从来没有在加载候选人之前添加 if (!IsPostBack),尽管它在你的回复中正盯着我看。我是觉得自己傻还是怎么的?感谢您的帮助以上是关于asp.net如何记住网页之间的变量值的主要内容,如果未能解决你的问题,请参考以下文章