Brent Oliver Brent Oliver - 2 months ago 9
ASP.NET (C#) Question

Session Variables not being seen/used

I have an aspx page that displays a gridview of questions waiting on review with 10 questions shown per page. If a question is selected it is opened in a new page where the reviewer can either submit a review or cancel and return to the list of questions needing review.

Currently this works fine, but have a request from the reviewers so that if they are on page 4 of the gridview when they go to a question, they get returned to page 4 if they hit cancel and return to the list of questions (currently they are returned to page 1).

So I am setting a couple session variables to capture the question selected and to capture the pageindex of the gridview control for future use. Trying to use the session variable for the questionId on the page load of the detail page, but it is not being passed. On returning to the Review List page the pageindex that is being set on the gridview is always 0, not the session variable.

Updated Gridview control (note two controls, one hyperlink(which should go away once the other linkbutton control works):

<asp:GridView ID="GridView1" runat="server" Caption="Questions Awaiting Review" AllowSorting="True" PagerSettings-Mode="NumericFirstLast" OnPageIndexChanging="GridView1_PageIndexChanging"
CaptionAlign="Top" EmptyDataText="No Questions Pending Review." PageSize="10" AllowPaging="true" PagerStyle-HorizontalAlign="Center" PagerStyle-Font-Size="Large" DataKeyNames="QuestionID"
AutoGenerateColumns="false" AlternatingRowStyle-BackColor="#cccccc">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="QuestionID" runat="server" Text='<%# Eval("QuestionID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="KeyObjective" HeaderText="Key Objective" ItemStyle-Width="250" />
<asp:BoundField DataField="SubmitDate" HeaderText="Submitted Date" ItemStyle-Width="60" />
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="Details" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") +"&PageIndex=" + GridView1.PageIndex %>'>View Question</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Details2" runat="server" Text="Session" OnClick="Session_OnClick"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>

</asp:GridView>


OnClick Event for the second button:

protected void Session_OnClick(object sender, EventArgs e)
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = GridView1.SelectedDataKey;
Response.Redirect("~/Review/ReviewDetail.aspx", false;

}


Connection string on the detail page which is now not getting a value for the parameter "QuestionID"; ):

SqlCommand command = new SqlCommand("QuestionDetail", Conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@QuestionID", SqlDbType.BigInt));

command.Parameters["@QuestionID"].Value = Convert.ToInt64(Session["QuestionId"]);
Conn.Open();
SqlDataReader reader = command.ExecuteReader();


PageLoad and gridview binding on the ReviewList page that should be using session variable to set page of grid control, but is always going to default of page 0:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindGridView();
}
else
{
if (Convert.ToInt32(Session["PageIndex"]) !=0)
{
GridView1.PageIndex = Convert.ToInt32(Session["PageIndex"]);
bindGridView();
}
}
}
private void bindGridView()
{
string connectionString = WebConfigurationManager.ConnectionStrings["CS1"].ConnectionString;
string selectSQL = String.Format("Select QuestionID, KeyObjective, SubmitDate from Questions where Author <> '{0}' and QuestionID not in(Select QuestionID from Review where Reviewer = '{0}')", User.Identity.Name);
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(selectSQL, con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();

adapter.Fill(ds, "Review");

GridView1.DataSource = ds;
GridView1.DataBind();

}

Answer

Your error probably means that Request["Id"] is empty or does not exists. Always check if QueryStrings exist and do the conversions of user inputs that are likely to fail inside a try-catch block.

    protected void Page_Load(object sender, EventArgs e)
    {
        long QuestionID = -1;

        //check if the Id QueryString exists
        if (Request.QueryString["Id"] != null)
        {
            //try to convert to int64
            try
            {
                QuestionID = Convert.ToInt64(Request.QueryString["Id"]);
            }
            catch
            {
            }
        }

        //if valid QuestionID
        if (QuestionID >= 0)
        {
            using (SqlConnection connection = new SqlConnection(Common.connectionString))
            using (SqlCommand command = new SqlCommand("QuestionDetail", connection))
            {
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.Add("@QuestionID", SqlDbType.BigInt).Value = QuestionID;

                //try to execute the stored procedure
                try
                {
                    connection.Open();
                    command.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    //handle sql error
                    Literal1.Text = ex.Message;
                }
            }
        }
    }

And why do you do a PostBack on the first button? That is not needed just to redirect to a different url. Change it to:

<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") %>'>View Question</asp:HyperLink>

Or with the Page Index also in the QueryString:

<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") + "&Page=" + GridView2.PageIndex %>'>View Question</asp:HyperLink>

UPDATE

If you really want to do a PostBack to set the Sessions you can use the OnRowCommand:

<asp:LinkButton ID="LinkButton1" CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="viewQuestion">View Question</asp:LinkButton>

CS

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "viewQuestion")
        {
            Session["PageIndex"] = GridView1.PageIndex;
            Session["QuestionId"] = e.CommandArgument.ToString();
            Response.Redirect("~/Review/ReviewDetail.aspx?Id=" + Convert.ToString(Session["QuestionId"]));
        }
    }