繁体   English   中英

如何记住web页asp.net之间的变量值

[英]How to remember variable value between web pages asp.net

我正在构建一个应用程序,可以为特定工作聘请顾问(候选人)。 在索引页面的一个表格中,随机加载了候选人的个人资料。 页面加载: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,但没有成功,这可能只是表明我并不真正理解它们是如何工作的。 当我将 DataList 和以下内容用于 HTML 中的按钮时,寻呼工作正常:

<asp:Button ID="BtnLearnMore" runat="server" Text="Learn More"
PostBackUrl='<%#"Candidate_Details.aspx?id="+Eval("IdCandidate")%>' 
/> 

但特别是对于这张桌子,我需要使用阅读器任何帮助将不胜感激!

在这部分代码中,您可以使用:

if (reader.Read())
{
    IdCandidateRemember=reader[“IdCandidate”].ToString();
    Session["IdCandidateRemeber"] = IdCandidateRemember; 
    LblIdCandidate.Text= IdCandidateRemember;
}

并且 IdCandidateRemeber 保存在 Session 变量中只要 session 持续时间,注意在完成使用时处理变量

然后在你的按钮中你可以使用

protected void BtnLearnMore_Click(object sender, EventArgs e)
{
    Response.Redirect("Candidate_Details.aspx?Id=" +  
    Convert.ToString(Session["IdCandidateRemember"]));
}

如果你打算只在一个页面中使用,你可以使用 ViewState 而不是 Session

好的,所以这是标准的公平。 您有一个应用程序,用户可能会说搜索酒店或其他内容。 你显示一个网格。

用户选择一个值。 现在是时候计算出该客户、该项目、该订单或其他任何内容的详细信息了。 飞机简数据库的东西 - 每天都做。

那么 web 这个概念是无状态的吗? (与桌面不同,您的代码值在其中保持不变?

好吧,在 web 土地上,每个页面回发,您的代码每次都从头开始!

因此,在每次 web 请求时都会创建页面 class 的“新”实例。 (除非您使用 ajax 调用 web 方法 - 但当您这样做时,您后面的代码将无法触及或查看任何控件值 - 因为它们在该页面回发发生之前不存在。

好的,那么你现在的设计模式是什么?

毕竟,就像任何应用程序一样,您可能会单击一行,然后显示详细信息或跳转到另一页以编辑该选项。

这里有几种方法。

首先,还是很常见?

您在 url 中传递值。实际上,在键入这篇文章时,我可以在 URL 中看到堆栈溢出代码使用的“消息”编号(值)。

你仍然看到亚马逊或其他服务经常在 url 中有很多“东西”。

www.mywebsite.com?&ID=134&Account=5454444

因此,您可以使用 URL 参数(通常称为查询值)将值传递给下一个 web 表单购买。 现在这种方法的问题是什么? 好吧,对于某些东西,比如数据库 PK 值,甚至是信用卡号? 您不希望该信息暴露给用户。 更糟糕的是,用户可能会“弄乱”并修改这些值。

现在,对于一个一般站点,说我们想要一个城市的人口? www.mywebsite.com/ShowPopulation.aspx?City= "纽约"

在上面,效果很好,因为最终用户甚至可以更改该值。

一些大型站点仍在使用这种方法,因为它在服务器端的成本为零(因此对于巨大的可扩展性,这种选择是可行的)。

然而,今天,我们有了更好的选择,我非常不喜欢那些乱七八糟的 URL。 它们可能会带来安全问题。

因此,您可以将行点击“ID”传递给 URL 中的下一个表单。

接下来?

视图状态:

ViewState 是每页的。 并且不暴露给 URL。因此这是一个很好的选择,我将结合为什么这个选择通常比下一个选择好得多。

Session:嗯,这个真的很漂亮。 它允许您将变量推送到 session() 中,并且它们在每个用户的应用程序范围内持久存在!!!

但是,你要小心使用 session() 不假思索!!!

假设我们有一个您要预订的酒店网格。

因此,您可以使用 session() 将此酒店“ID”传递给下一个表单。

然而,如果同一用户启动另一个浏览器页面并选择不同的酒店,然后跳转到酒店预订页面,会发生什么情况。 如果我们将酒店 ID 存储在 session() 中?

对于那个用户来说,它是应用程序范围内的。 所以? 现在在酒店预订上打开了两个 web 页面,我们将在 session 中获得错误的 pk id。如果你说要买房子? 然后,您要么不允许一个用户打开一个以上的购房页面,要么您只使用 session 来传递值。

所以,我所做的是使用 session() 将值传递给下一个表单,然后立即将传递的值移动到 ViewState。 (因为视图 state 是每页)。

所以,让我们填充一个网格,select 网格中的一家酒店,然后跳转到下一页。

所以说我们有这个:

    <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() 传递值的“规则”是可以的,但请注意我做的第一件事是如何将 session 传输到 ViewState。 我这样做是因为用户可以右键单击,甚至可以启动另一个浏览器。 因此,如果有两家酒店开放,那么两个页面都可以正常运行,我不在乎 session 值是否发生了变化。

坚持的另一种方法?

我们经常使用 web 页面上的控件——甚至是隐藏控件。 这通常很方便,因为客户端 JS 代码也可以在页面上使用这些值。

所以,这应该给你一些想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM