Как запомнить значение переменной между веб-страницами asp.net

#c# #html #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, предназначенный для запоминания. Я пытался использовать сеанс и строку запроса, но безуспешно, что, вероятно, просто показывает, что я на самом деле не понимаю, как они работают.
Вызов страницы отлично работает, когда я использую DataList и следующее для кнопки в HTML:

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

Но для этой таблицы, в частности, мне нужно использовать считыватель
Любая помощь будет очень признательна!

Комментарии:

1. На самом деле это не вопрос кодирования, больше дизайна/архитектуры, выяснения того, что ваши страницы должны делать, а чего не делать. Загрузка пользователя-когда вы действительно хотите указать странице, какого пользователя загружать, — кажется, проблема. Возможно, вам понадобится совершенно новая страница для сведений о пользователе.

2. Спасибо вам за ваш ответ. Страница сведений:; Candidate_Details.aspx, которая хорошо работает. Для всех кандидатов используется один и тот же формат страницы, и для каждого кандидата загружаются соответствующие сведения о кандидате. Когда он вызывается с помощью этого: PostBackUrl='<%#»Candidate_Details.aspx?id=» Eval(«IdCandidate»)%>» он отлично работает. Моя проблема в том, что я не знаю, как отправить идентификатор IdCandidate на страницу сведений с помощью считывателя, в отличие от обработчика данных.

3. Я думаю, что эта проблема уже задавалась раньше, если не здесь, то в Интернете. Это не совсем простой IIRC из-за закрытия соединения или что-то в этом роде, верно? Я могу ошибаться на этот счет. Возможно, вам понадобится другой подход, но я уверен, что видел сообщения или статьи об этом. Чтобы получить лучшую помощь здесь, вам следует отредактировать свой вопрос и избавиться от всего лишнего. Используйте последнее предложение вашего последнего комментария в качестве основы для вашего вопроса и избавьтесь от остального.

Ответ №1:

В этой части кода вы можете использовать :

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

и IdCandidateRemeber был сохранен в переменной сеанса до тех пор, пока продолжительность сеанса, будьте готовы удалить переменную, когда закончите использовать

затем в своем боттоне вы можете использовать

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

если вы собираетесь использовать только одну страницу, вы можете использовать ViewState вместо сеанса

Комментарии:

1. Я приношу извинения за задержку с ответом. Наконец-то у меня получилось. Ваше предложение сработало. Я долго не мог заставить его работать, потому что мне не удалось добавить if (!IsPostBack) перед загрузкой кандидатов. Действительно, глупая ошибка! Спасибо вам за вашу помощь.

Ответ №2:

хорошо, значит, это стандартная ярмарка. У вас есть приложение, пользователь может сказать «поиск отеля» или что-то в этом роде. вы отображаете сетку.

Пользователь выбирает значение. Теперь пришло время проработать детали этого клиента, или этого проекта, или этого заказа, или чего-то еще. Дела с базой данных самолета Джейн — делаются каждый день.

Итак, пока веб-концепция не имеет состояния? (в отличие от рабочего стола, в котором значения вашего кода остаются неизменными?

Что ж, в веб-стране, на каждой обратной странице ваш код каждый раз начинается с нуля!

Таким образом, «новый» экземпляр класса страницы создается при каждом веб-запросе. (если вы не используете ajax — вызов веб — метода, но когда вы это делаете, ваш код не может ни касаться, ни просматривать какие-либо значения элементов управления, поскольку они не существуют до тех пор, пока не произойдет обратная публикация страницы.

Хорошо, так каков же ваш шаблон дизайна сейчас?

В конце концов, как и в любом приложении, вы можете нажать на строку, а затем отобразить сведения или перейти на другую страницу, чтобы сказать «изменить этот выбор».

здесь есть несколько подходов.

Первый, и все еще очень распространенный?

Вы передаете значения в URL-адресе. На самом деле, набирая это сообщение, я вижу номер (значение) «сообщения», используемый кодом при переполнении стека в URL-адресе.

и вы все еще видите, что amazon или другие сервисы ЧАСТО содержат много «вещей» в URL-адресе.

 www.mywebsite.com?amp;ID=134amp;Account=5454444
 

Таким образом, вы можете передавать значения в следующую веб-форму, используя параметры URL (часто называемые значениями запроса). Теперь в чем проблема с таким подходом? Ну, для определенных вещей, таких как значение PK в базе данных или, скажем, даже номер кредитной карты? Вы не хотите, чтобы эта информация была доступна пользователю. Хуже того, пользователь может «возиться» с этими значениями и изменять их.

Теперь для общего сайта, и, скажем, нам нужно население города? www.mywebsite.com/ShowPopulation.aspx?City=»Нью-Йорк»,

В приведенном выше, это отлично работает, так как значение может даже быть изменено конечным пользователем.

И некоторые крупные сайты часто используют этот подход, так как на стороне сервера он стоит НОЛЬ (так что для огромной масштабируемости этот выбор может сработать).

Однако сегодня у нас есть гораздо лучшие варианты, и мне очень нравятся эти грязные URL. И они могут создавать проблемы с безопасностью.

Таким образом, вы можете передать строку «ИДЕНТИФИКАТОР» в следующую форму в URL-адресе.

Следующий шаг?

Состояние просмотра:

Состояние просмотра указано на странице. И НЕ отображается URL-адрес. Таким образом, это отличный выбор, и я объясню, почему этот выбор часто НАМНОГО лучше, чем следующий.

Сессия: Ну, этот действительно очень хорош. Это позволяет вам вставлять переменные в session(), и они сохраняются ДЛЯ КАЖДОГО ПОЛЬЗОВАТЕЛЯ в рамках всего приложения!!!

Однако вы должны быть осторожны, чтобы использовать session() не задумываясь!!!

Допустим, у нас есть сетка отелей, которые вы хотите забронировать.

Таким образом, вы можете использовать session() для передачи этого идентификатора отеля в следующую форму.

Однако теперь, что произойдет, если тот же пользователь запустит другую страницу браузера, выберет другой отель и перейдет на страницу бронирования отеля. Если бы мы сохранили идентификатор отеля в сеансе()?

Это широкое приложение для этого одного пользователя!!! Итак, теперь, когда при бронировании отеля открыты две веб-страницы, в сеансе у нас будет НЕПРАВИЛЬНЫЙ идентификатор пк. А если вы скажете о покупке дома? Тогда либо вы не разрешаете одному пользователю открывать более одной страницы покупки жилья, либо используете сеанс ТОЛЬКО для передачи значений.

Итак, я использую session() для передачи значения(значений) в следующую форму, а затем немедленно перемещаю это переданное значение(значения) в состояние просмотра. (поскольку состояние просмотра указано на странице).

Итак, давайте заполним сетку, выберем отель из сетки, а затем перейдем на следующую страницу.

Итак, допустим, у нас есть это:

     <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();
        }
    }
 

Хорошо, теперь у нас есть это:

введите описание изображения здесь

Хорошо, давайте используем сеанс для перехода по щелчку строки на следующую страницу (скажем, в форме сведений для отображения информации об отеле).

таким образом, код нажатия кнопки может быть таким (получает идентификатор строки PK).

    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 в сеанс(). (сеанс = глобальный = для каждого пользователя)

Итак, теперь на целевой странице мы можем сделать это:

     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() для передачи значений в порядке, но обратите внимание, что первое, что я делаю, — это переношу сеанс в состояние просмотра. Я делаю это, так как пользователь может щелкнуть правой кнопкой мыши или даже запустить другой браузер. Итак, если открыты два отеля, то обе страницы будут работать просто отлично, и мне все равно, что значение(значения) сеанса изменилось.

Другой подход к сохранению?

Мы часто используем элементы управления на веб — странице-даже скрытые. Это часто бывает удобно, так как JS-код на стороне клиента также может использовать такие значения на странице.

Итак, это должно натолкнуть вас на некоторые идеи.

Комментарии:

1. Точно так же, как я сказал Оскару: извините за задержку в моем ответе. Наконец-то у меня получилось. Ваши предложения сработали. Я никогда не добавлял if (!IsPostBack) перед загрузкой кандидатов, несмотря на то, что он смотрел прямо на меня в вашем ответе. Я чувствую себя глупо или как? Спасибо вам за вашу помощь