可以从@Page访问Session变量,但不能从底层Class访问

时间:2012-08-16 18:09:16

标签: c# asp.net session variables session-variables

当用户登录时,我的代码会在System.Web.HttpContext.Current.Session["customer_ref"]内使用HandleUserLogin()设置会话变量。

我在下面的课程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;
    }
}

设置此Session变量后,我很高兴能够使用以下代码在页面上显示它,并且我将其设置的值显示得非常好。

<%@ 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(),该类在构造时尝试访问Session变量。

以下是dashboard.aspxdashboard.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();
            }

    }
}

2 个答案:

答案 0 :(得分:2)

您已将SessionManager设为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类型。这样,您就不必将相同的代码片段复制到需要用户登录的所有页面。

或者(正如我在你之前的一个问题的回答中写的那样)你可以继续使用custom MembershipProvider实现身份验证,并让框架处理所有的管道。

答案 1 :(得分: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,而它尚未创建。