Background and How Sessions Are Implemented ASP.NET provides a framework for storing data that is specific to an individual user with the Session object. A page can add information to the Session object, and any other page can then retrieve the information for the same user. In order to preserve server memory, ASP.NET implements a rolling timeout mechanism which discards the session information for a user if no request is seen within the timeout period (default 20 minutes which is reset with each request). It is often useful in an ASP.NET site to know for a particular request if the user’s session information is still intact (that a timeout has not occurred). One common need is to be able to inform the user why they lost their session information, by redirecting to a page that describes the timeout amount and how to avoid the problem in the future.  Without this technique it is difficult to know if a session variable is not present whether it was never set properly or the user waited too long between requests.  Many ASP.NET developers just reference session variables without first ensuring they are actually present.  This causes the infamous "Object reference not set" exception, which can be very difficult to trace back to the specific cause.  Code that checks for null session values is useful, but does not help the developer understand if it was never set properly or if the user just lost her session.  This technique can help to clearly identify that the user waited to long between requests and the session storage information was removed.This is not the same as using the Session_OnEnd event which can be used for cleanup, logging, or other purposes.  It is also not for enforcing security on a web site.  How Sessions Are Implemented 
Since the HTTP protocol used by web browsers to request files from web servers is stateless, ASP.NET needs to determine which requests were from the same user. The primary mechanism utilizes a non-persistent cookie that is issued by the web server that contains a session id value. The id provided by this cookie is the key used to index into the session infrastructure to access the user's specific data. The session framework is implemented by the HTTP module System.Web.SessionState.SessionStateModule, which executes before the .aspx page events. The module uses the EnableSessionState attribute from the @Page directive to determine if it must retrieve the user’s session information (and whether it needs to write out changes when the request is complete). If the EnableSessionState attribute is true (which it is by default), the module retrieves all of the user’s session information and sets the Session property of the Page class to an instance of the HttpSessionState class. This article focuses on the cookie mechanism, although a cookie-less method of sessions is implemented in ASP.NET (the session id is embedded in the URL string). The Session information can be stored in-process (default, stores in web server memory), with a state service, or a SQL Server database. This article will focus on the in-process storage, but the technique applies to all three locations. Example User Session 
A user opens a browser instance and requests an ASP.NET page from a site. If the EnableSessionState attribute is true, the session module adds the ASP.NET_SessionId cookie to the response. On subsequent requests to the same web site, the browser supplies the ASP.NET_SessionId cookie which the server side module uses to access the proper user’s information. 
 
Detecting Timeouts The ASP.NET HttpSessionState class provides a useful IsNewSession( ) method that returns true if a new session was created for this request.  The key to detecting a session timeout is to also look for the ASP.NET_SessionId cookie in the request.  If this is a new session but the cookie is present, this indicates a timeout situation.  In order to implement this effectively for an entire web site, it is useful to utilize the “Base Page” concept described in a previous article.
basePageSessionExpire.cs
 public class basePageSessionExpire : System.Web.UI.Page
 {
    public basePageSessionExpire()
    {
    }
  override protected void OnInit(EventArgs e)
  {
       base.OnInit(e);
   //It appears from testing that the Request and Response both share the 
   // same cookie collection.  If I set a cookie myself in the Reponse, it is 
   // also immediately visible to the Request collection.  This just means that 
   // since the ASP.Net_SessionID is set in the Session HTTPModule (which 
   // has already run), thatwe can't use our own code to see if the cookie was 
   // actually sent by the agent with the request using the collection. Check if 
   // the given page supports session or not (this tested as reliable indicator 
   // if EnableSessionState is true), should not care about a page that does 
   // not need session
   if (Context.Session != null)
   {
    //Tested and the IsNewSession is more advanced then simply checking if 
   // a cookie is present, it does take into account a session timeout, because 
   // I tested a timeout and it did show as a new session
    if (Session.IsNewSession)
    {
     // If it says it is a new session, but an existing cookie exists, then it must 
   // have timed out (can't use the cookie collection because even on first 
   // request it already contains the cookie (request and response
     // seem to share the collection)
     string szCookieHeader = Request.Headers["Cookie"];
     if ((null != szCookieHeader) && (szCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
     {
      Response.Redirect("sessionTimeout.htm");
     }  
    } 
   }
  }
}sessionTimeout.htmThis can be any page on the site, example just redirects to this page so just show a simple "A timeout has occurred" message for this article.Each other page on the site just needs to derive from this new base page instead of the default System.Web.UI.Page, so just change the line in the code behind class from ": System.Web.UI.Page" to ": basePageSessionExpire".  Each page should also set the EnableSessionState variable as appropriate:false - page request does not access any session information (the base page uses this to know that it does not need to check for timeout on this request since it does not require session information)  
ReadOnly - page request uses session information but does not modify it 
true - page request reads and updates session information
Conclusion
It is often useful to know for a given request whether the user’s session information is still present.  The technique demonstrated is a straightforward implementation that can be easily applied to an entire web site that uses cookie based ASP.NET Session objects. 
 

解决方案 »

  1.   

    http://aspalliance.com/520_Detecting_ASPNET_Session_Timeouts.all
      

  2.   

    http://forums.asp.net/t/1245925.aspx
      

  3.   

    http://support.microsoft.com/kb/317604
      

  4.   

    ************ HomePage.aspx.cs **************
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" 
                onrowdatabound="GridView1_RowDataBound">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:HyperLink ID="HyperLink1" Target="_blank" Text="View" runat="server"></asp:HyperLink>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField HeaderText="ID" DataField="ID" />
                <asp:BoundField HeaderText="Name" DataField="Name" />
            </Columns>
            </asp:GridView>
        </div>
        </form>
    </body>
    </html>************ HomePage.aspx.cs **************
        protected void Page_Load(object sender, EventArgs e)
        {
            DataTable table = new DataTable();
            if (!Page.IsPostBack)
            {
                table.Columns.Add("ID",typeof(int));
                table.Columns.Add("Name", typeof(string));
                table.Rows.Add(1,"abc");
                table.Rows.Add(2, "efg");
                GridView1.DataSource = table;
                GridView1.DataBind();
            }
        }    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                HyperLink link = (HyperLink)e.Row.FindControl("HyperLink1");
                link.NavigateUrl = string.Format("http://YourWebSite/ViewBookReview.aspx?BookID={0}",e.Row.Cells[1].Text);
            }
        }
      

  5.   

    1,当datasource没有数据时,也显示Header。 
    /**//// <summary>
        /// 绑定GridView控件(当DataSet为空时也显示GridView的表头)
        /// </summary>
        /// <param name="gridView">所要绑定的GridView</param>
        /// <param name="ds">所要绑定的数据集</param>
        /// <returns>void </returns>
        public void BindGridView(GridView gridView, DataSet ds)
        ...{
            if (ds.Tables[0].Rows.Count > 0)
            ...{
                gridView.DataSource = ds;
                gridView.DataBind();
            }
            else
            ...{
                ds.Tables[0].Rows.Add(ds.Tables[0].NewRow());
                gridView.DataSource = ds;
                gridView.DataBind();
                int columnCount = gridView.Rows[0].Cells.Count;
                gridView.Rows[0].Cells.Clear();
                gridView.Rows[0].Cells.Add(new TableCell());
                gridView.Rows[0].Cells[0].ColumnSpan = columnCount;
                gridView.Rows[0].Cells[0].Text = "没有数据";
                gridView.RowStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
            }
        }
     //------------------------------调用实例--------------------------------
    string connString = "server=(local);uid=sa;pwd=;database=pubs";
    string cmdText = "select * from authors";
    SqlConnection conn = new SqlConnection(connString);
    SqlDataAdapter adp = new SqlDataAdapter(cmdText, conn);
    DataSet ds = new DataSet();
    adp.Fill(ds);
    BindGridView(this.GridView1, ds);
      

  6.   

    I have a problem with viewState for one page.This page is calling from another site, and IIS is prohobiting access because viewState of request is invalid.I tryed to disable this by this attribute in first line of aspx page:EnableViewState="false"But it does not help
    ======================
    Hi try below code in page_init method  override protected void OnInit( EventArgs e ) {if (Request.Browser.MSDomVersion.Major == 0) // If it is Non IE Browser
                {
                    Response.Cache.SetNoStore(); // Disable to Client side Cache.
                };base.OnInit( e ); 
    }
      

  7.   

    viewstate:http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic3
    如何设计viewstate(使某些控件viewstate不可用,减轻网页负载,如何观察)
      

  8.   

    How to do a Form Post in .Net 2.0
    http://forums.asp.net/t/1112585.aspx
    http://www.netomatix.com/development/postrequestform.aspx
    Hello Si,You can use HttpWebRequest to post data to another website, please read the following to make clear how to do it.How to use HttpWebRequest to send POST request to another web server?
    In classic ASP applications we had the flexibility of having multiple form tags on the same page and each form could have different target URLs and different method types. This has been kind of a limiting factor in ASP.Net applications. But this does not mean that it can not be accomplished. Micorosoft .Net framework has a very rich library and provides answers to most of the questions. It has a very handy HttpWebRequest class that can be used to send HTTP requests to any server. Where do I need to use it?
    Its is important to know where this feature is required. A very good example is if you are using Paypal to accept payments for your e-commerce application. It requires that you set up your shopping cart button to submit a POST request with all the required information. Following is an example from Paypal's developer support web site. <form name="_xclick" target="paypal"
    action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_cart">
    <input type="hidden" name="business" value="[email protected]">
    <input type="hidden" name="item_name" value="HTML book">
    <input type="hidden" name="amount" value="24.99">
    <input type="image" src="http://www.paypal.com/images/sc-but-01.gif"
    border="0" name="submit" alt="Make payments with PayPal!">
    <input type="hidden" name="add" value="1">
    </form>
    You can see that when you click on this button, a form will be submitted to paypal. The problem is that ASP.Net does not allow embedding of second form tag inside the main form. How will I do it?
    We will gather all the required information from the user on a regular ASPX page. And then when user clicks button to submitt information for shopping cart, then we will use HttpWebRequest object to submit the request to target web server. The following illustrates how values from two text box controls are sent to a target web server. This example does not correspond to the fields described in the Paypal example. private void OnPostInfoClick(object sender, System.EventArgs e)
    {
    string strId = UserId_TextBox.Text;
    string strName = Name_TextBox.Text; ASCIIEncoding encoding=new ASCIIEncoding();
    string postData="userid="+strId;
    postData += ("&username="+strName);
    byte[]  data = encoding.GetBytes(postData); // Prepare web request...
    HttpWebRequest myRequest =
      (HttpWebRequest)WebRequest.Create("http://localhost/MyIdentity/Default.aspx");
    myRequest.Method = "POST";
    myRequest.ContentType="application/x-www-form-urlencoded";
    myRequest.ContentLength = data.Length;
    Stream newStream=myRequest.GetRequestStream();
    // Send the data.
    newStream.Write(data,0,data.Length);
    newStream.Close();
    }
    If your server is capable of sending compressed response, read our article How to use Accept-Encoding HTTP Header for more details about it. Another realted article about posting data to another web server and directing user to that site with it is is posted here Post Request To Another Web Site With Redirection. See also How to use HttpWebRequest to simulate Hotmail Login?