2012-08-16 91 views
0

当用户登录时,我的代码使用System.Web.HttpContext.Current.Session["customer_ref"]HandleUserLogin()内设置Session变量。可以从@Page访问会话变量,但不能从基础类访问会话变量

我这样做是在下面的类,SessionManager

SessionManager.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

/// <summary> 
/// Summary description for Session 
/// </summary> 
public class SessionManager 
{ 
    public string customer_ref; 
    public bool logged_in = false; 

    public SessionManager() 
    { 

     // 
     // NULL REFERENCE EXCEPTION CAUSED HERE 
     // 
     // 
     // Check to see if the user is logged in (is a customer reference set?) 
     if (System.Web.HttpContext.Current.Session["customer_ref"] != null) 
     { 

      // The user is logged in 
      logged_in = true; 
     } 

    } 

    public bool HandleUserLogin(string username, string password) 
    { 
     if ((!string.IsNullOrEmpty(username)) && (!string.IsNullOrEmpty(password))) 
     { 
      // Check that the username and password are valid 
      if ((!string.IsNullOrEmpty(username)) && (password == "password")) 
      { 
       // Generate a new session ID 
       // TODO: Find out how to. 

       // Set the session variables 
       System.Web.HttpContext.Current.Session["customer_ref"] = username; 

       // Set the variables of this Session object for future use 
       this.customer_ref = username; 

       // Set the logged in status to true 
       this.logged_in = true; 

       return true; 
      } 
      else 
      { 
       // Username and password are incorrect 
       return false; 
      } 
     } 

     // The username or password was not entered 
     return false; 
    } 

    public void HandleUserLogout() 
    { 
     System.Web.HttpContext.Current.Session["customer_ref"] = null; 

     // Unset the variables in the SessionManager object 
     this.customer_ref = string.Empty; 

     // Set the logged in status to false 
     this.logged_in = false; 
    } 
} 

一旦会话变量设置,我很高兴地能够表明它在页面上使用下面的代码和我设置它的值很好地显示。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableSessionState="True" %> 

<!DOCTYPE html> 

<html> 

<head> 
</head> 
<body> 
      <% 
       // 
       // WRITE THE CUSTOMER REFERENCE FROM THE SESSION 
       // 
       Response.Write(System.Web.HttpContext.Current.Session["customer_ref"]); 
      %> 

</body> 
</html> 

但是,我不能从所谓的dashboard.aspx另一个页面访问它,因为它抛出一个NullReferenceException当我打电话给我的SessionManager()类试图在构造访问会话变量。

下面是dashboard.aspx代码,dashboard.aspx.cs

dashboard.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="dashboard.aspx.cs" Inherits="dashboard" MasterPageFile="~/Design.master" EnableSessionState="True" %> 

<asp:Content ID="customer" ContentPlaceHolderID="CustomerInfo" runat="server">    
    <div class="customer_name"><% Response.Write(customer.customer_name); %></div> 
    <div class="customer_account_number">Account number: <% Response.Write(customer.customer_ref); %></div> 
</asp:Content> 


<asp:Content ID="outstanding_orders" ContentPlaceHolderID="Content" runat="server"> 

    <div class="content_left_title_wrapper"> 
     <h2 class="content_left_title">Your Outstanding Orders</h2> 
    </div> 

    <table id="outstanding_orders" cellpadding="0" cellspacing="0"> 
    <colgroup span="4"></colgroup> 
    <colgroup span="1" class="view_link_col"></colgroup> 
     <tr> 
      <th><div>Order Number</div></th> 
      <th><div>Date Placed</div></th> 
      <th><div>Total Cost</div></th> 
      <th><div>Order Status</div></th> 
      <th></th> 
     </tr> 

     <% 
      // Loop through all of the outstanding orders for the customer 
      foreach (OrderSummary order_item in outstanding_orders) 
      { 
     %> 

     <tr> 
      <td><div><% Response.Write(order_item.order_number); %></div></td> 
      <td><div><% Response.Write(order_item.uk_order_date); %></div></td> 
      <td><div>£<% Response.Write(order_item.order_total); %></div></td> 
      <td><div>Incomplete</div></td> 
      <td><div><a href="orderlines.aspx?orderno=<% Response.Write(order_item.order_number); %>" class="order_detail_link">Detail<br /><img src="images/design/view_order_arrow.png" /></a></div></td> 
     </tr> 

     <% 
      } 
     %>     

    </table> 

</asp:Content> 

dashboard.aspx.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

using IBMU2.UODOTNET; 
using System.Xml.Linq; 

public partial class dashboard : System.Web.UI.Page 
{ 
    // Get the users session 
    SessionManager session = new SessionManager(); 

    // Create a new connection to the database 
    ReflexDatabase db_con = new ReflexDatabase(); 

    // Blank list to hold the orders 
    public List<OrderSummary> outstanding_orders = new List<OrderSummary>(); 

    public XDocument test { get; set; } 

    public Customer customer; 

    // OnInit is called before the page loads (See internet for ASP.NET Page Lifecycle) 
    protected override void OnInit(EventArgs e) 
    { 

     if (session.logged_in == false) 
     { 

      // I've tried it here, and it won't redirect 
      Response.Redirect("default.aspx"); 
     } 

    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 

      try 
      { 

       // Create the customer as a Customer object 
       customer = new Customer(session.customer_ref); 

       // Query the TOELINE database 
       XDocument customer_orders = db_con.Query(String.Format("LIST TOEHEAD BY.DSND ORDERNO WITH CUSREF = \"{0}\" AND ORDERSTATUS < 50 ORDERNO DATEONFILE T.VAL.TO.INV ORDERSTATUS TOXML ELEMENTS", customer.customer_ref)); 

       test = customer_orders; 

       // Use LINQ to pipe the data in to OrderSummary objects 
       var linqQuery = from n in customer_orders.Element("ROOT").Descendants("TOEHEAD") 
           select new OrderSummary 
           { 
            //order_number = n.Element("ORDERNO").Nodes()..ToString(), 
            order_number = n.Descendants("ORDERNO").First().Value, 
            us_order_date = n.Descendants("DATEONFILE").First().Value, 
            order_total = n.Descendants("T.VAL.TO.INV").First().Value 
           }; 

       // Add all of the items to the list of orders outstanding for the customer 
       foreach (OrderSummary linqItem in linqQuery) 
       { 
        outstanding_orders.Add(linqItem); 
       } 

      } 
      finally 
      { 
       // Close the session to prevent hogging of sessions 
       db_con.CloseSession(); 
      } 

    } 
} 
+0

这里''

您从变量读它从会议看它像这样'System.Web.HttpContext.Current.Session [“customer_ref”]' – 2012-08-16 18:25:42

+0

@WaqarJanjua请'SessionManager.cs'看到我有注意** NULL引用异常导致**,这是发生异常的地方。 – Luke 2012-08-16 18:32:28

+0

在OnInit和PageLoad方法中创建SessionManager会话对象,而不是在Page级别创建。 – 2012-08-16 18:52:50

回答

2

所做的SessionManager一个实例成员的Page。这意味着初始化器将在页面处理器运行Page构建器之前运行(我认为)。

而这种情况发生在Session已被添加到HttpContext对象之前。

尝试改变这一行:

SessionManager session = new SessionManager(); 

SessionManager session = null; 

再新它(例如)的OnInit方法了(另外,不要忘记调用base.OnInit()):

protected override void OnInit(EventArgs e) 
{ 
    session = new SessionManager(); 
    if (session.logged_in == false) 
    { 
     Response.Redirect("default.aspx"); 
    } 
    base.OnInit(e); 
} 

如果这将是您的身份验证方案,您可能不想创建自定义BasePage类型您的其他网页可能来自哪个pe。这样你就不需要将相同的代码复制到需要用户登录的所有页面。

或者(正如我已经写过一个答案,你的前一个伫列),你可以去提前并使用custom MembershipProvider实施认证,并让框架处理所有管道。

+0

感谢您的回复。一旦我掌握了其他内容,我将解决MembershipProvider问题。我注意到,当我尝试通过Page_Load()方法访问它们时,我的会话变量也会导致异常,无论该SessionManager类是否在'OnInit()'方法内。在页面呈现之前检索会话变量的正确位置在哪里?再次感谢你的耐心,我再次感觉像是一名初学者。我在PHP中知道所有这些东西。 :( – Luke 2012-08-16 19:01:23

+0

@ user1429080:我赞成你的,你更彻底 – fowlermatthewd 2012-08-16 19:07:39

0

一旦创建了仪表板(页面)对象,就会创建SessionManager的实例。你可以把它改成:

// Get the users session 
    SessionManager session = null; 

... 

protected override void OnInit(EventArgs e) 
    { 
     session = new SessionManager(); 

.. 
} 

,或者你可以把这个逻辑,并把它放在它自己的方法代替邻构造

public bool IsLoggedIn() 
    { 
    if (System.Web.HttpContext.Current.Session["customer_ref"] != null) 
    { 

     // The user is logged in 
     logged_in = true; 
    } 
    } 

有几个选择,但问题是,因为SessionManager类的构造函数正在调用Session,并且它尚未创建。