簡體   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