0

ユーザーがログインすると、私のコードはSystem.Web.HttpContext.Current.Session["customer_ref"]、内で、を使用してSession変数を設定します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>

ただし、構築時にSession変数にアクセスしようとするクラスを呼び出すと、dashboard.aspxがスローされるため、と呼ばれる別のページからアクセスできません。NullReferenceExceptionSessionManager()

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

    }
}
4

2 に答える 2

2

SessionManagerインスタンスをのメンバーにしましたPage。つまり、初期化子は、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タイプを作成したくない場合があります。そうすれば、ユーザーがログインする必要のあるすべてのページに同じコードをコピーする必要がありません。

または(以前の質問への回答ですでに書いたように)、カスタムMembershipProviderを使用して認証を実装し、フレームワークにすべての配管を処理させることができます。

于 2012-08-16T18:38:04.227 に答える
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を呼び出しており、まだ作成されていないためです。

于 2012-08-16T18:38:13.797 に答える