在非XXX.aspx.cs檔案中使用Response、Request對像

iDotNetSpace發表於2009-07-06

在非XXX.aspx.cs檔案中使用Response、Request對像,即在aspx檔案的CodeFile檔案(Code Behind分離的程式碼檔案)之外使用Response、Request對像。

相信有過ASP.NET開發經驗的網友對Response、Request物件絕對不陌生,它們的作用與好處並不是本文討論的範圍。通常我們在XXX.aspx.cs檔案中直接使用Response、Request物件,比如我們有一個頁面(通常指所謂的後臺管理頁面)需要登入才能訪問,直接訪問這個頁面,如果程式檢測到使用者沒有登入就跳轉到登入頁,程式碼如下:

protected void Page_Load(object sender, EventArgs e)
{
    
if (Session["UserName"!= null)
    {
        
//
        
// TODO: 在此處新增通過登入驗證邏輯
        
//
    }
    
else
    {
        Response.Redirect(
"Login.aspx");
    }
}

可以看到上面我們使用了Response和Session物件,現在我們假設一下我們有好多頁面都要用這樣的程式碼對使用者的登入情況進行判斷,難道我們要重複在不同的頁面上書寫這段同樣的程式碼嗎,顯然這很不科學,我們需要重構、重用程式碼。

通常我們把一些實用方法放在App_Code資料夾中供我們重複利用,那麼這裡的Session驗證與轉頁面方法能不能封裝在App_Code資料夾中的某個cs檔案裡呢?然後在需要呼叫的XXX.aspx.cs檔案中像下面那樣直接呼叫,那天我們要轉向的登陸頁面地址變了也只要改一下App_Code資料夾中的cs檔案,而不用每個XXX.aspx.cs檔案都要去重新修改:

protected void Page_Load(object sender, EventArgs e)
{
    Accounts.CheckLogin();
}

上面Accounts.CheckLogin();方法負責檢測使用者登入,內部包含了跳轉頁面處理邏輯。

我們先來分析一下,在自動生成的XXX.aspx.cs檔案中我們可以看到下面這樣的程式碼。

public partial class _Default : System.Web.UI.Page 
{
    
protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(
"Some text!");
    }
}

在Visual Studio中將滑鼠移到“Response”上面,IDE提示這裡的“Response”物件是System.Web.UI.Page成員,這是不是意味著我們在App_Code資料夾中的cs檔案建立一個類,並讓這個類繼承自System.Web.UI.Page這個類,然後就可以一樣像在XXX.aspx.cs檔案中那樣直接使用Response和Session等物件呢?比如像下面那樣(App_Code/ Accounts.cs):

public class Accounts : System.Web.UI.Page
{
    
public Accounts()
    {
        Response.Write(
"Some text!");
    }
}

上面的程式碼僅管編譯能通過,但真正把程式執行起來後,你會發現報錯了,報“響應在此上下文中不可用”。這裡有一個“上下文”的概念,英文譯為“Context”,下面的“HttpContext”則是“Http上下文”的意思。這裡之所以會報錯,據MSDN介紹,由於HTTP的無狀態特性,Web應用程式需要跟蹤上下文片段。比如在XXX.aspx.cs檔案中可以用“Request.Url”獲取當前請求的URL資訊,而你如果把Request.Url這個方法直接定義在App_Code資料夾中的某個cs檔案裡,然後在外面直接呼叫,程式就不知道你要的是那個頁的Response,即沒有參考環境,因為App_Code資料夾的cs檔案是不直接提供給瀏覽器訪問的。微軟提供的Context實用物件實現了方法呼叫處上下文的動態封裝。即我們在外面定義的含有Response物件的方法,這個方法在那個頁面(通常為aspx頁面)被呼叫,就能準確獲取到當前請求頁的上下文物件集合,相當好用。

然後我們把程式碼改成這樣:

public class Accounts
{
    
public Accounts()
    {
        HttpContext.Current.Response.Write(
"Some text!");
    }
}

現在一切正常了,這裡的HttpContext是System.Web名字空間下的。通過HttpContext.Current我們還可以點出下面常見的物件或類:

HttpContext.Current.Response
HttpContext.Current.Request
HttpContext.Current.Server
HttpContext.Current.Request.Cookies

另外還包含以下物件:Application、ApplicationInstance、Cache、Error、Items、Trace、User,具體使用方法可以自己去參考MSDN並試驗。

讀到這裡,相信你應該恍然大悟,也應該知道自己該如何做了。下面是我做的一個Demo,一共3個cs檔案,程式碼很簡單,一看就明白,後面提供例項原始碼下載。

1、App_Code/ Accounts.cs

/// 
/// 使用者登入、登出類
/// 
public class Accounts
{
    
public Accounts()
    {
        
//
        
// TODO: 在此處新增建構函式邏輯
        
//
    }
    
public static void CheckLogin()
    {
        
if (HttpContext.Current.Session["UserName"== null)
            HttpContext.Current.Response.Redirect(
"Login.aspx");
    }
    
public static void CheckLogin(string goUrl)
    {
        
if (HttpContext.Current.Session["UserName"== null)
            HttpContext.Current.Response.Redirect(goUrl);
    }
    
public static void Login(string userName, string passWord)
    {
        
if (userName == "admin" && passWord == "admin888")
        {
            HttpContext.Current.Session[
"UserName"= userName;
            HttpContext.Current.Response.Redirect(
"Default.aspx");
        }
        
else
        {
            HttpContext.Current.Response.Redirect(
"Login.aspx");
        }
    }
    
public static void Logout()
    {
        HttpContext.Current.Session[
"UserName"= null;
        HttpContext.Current.Response.Redirect(
"Default.aspx");
    }
    
public static void Logout(string goUrl)
    {
        HttpContext.Current.Session[
"UserName"= null;
        HttpContext.Current.Response.Redirect(goUrl);
    }
}

2、Default.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    Accounts.CheckLogin();
    
this.UserName.Text = Session["UserName"].ToString();
}
protected void Logout_Click(object sender, EventArgs e)
{
    Accounts.Logout();
}

3、Login.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLogin_Click(object sender, EventArgs e)
{
    Accounts.Login(
this.UserName.Text,this.PassWord.Text);
}

我對App_Code/ Accounts.cs下的幾個方法進行了過載,以便靈活呼叫。下面程式碼是在頁面一載入的時候用Accounts.CheckLogin();先檢查使用者登入情況,只有登入成功本方法後面程式碼才有機會執行,因為不成功直接被轉頁面了。

protected void Page_Load(object sender, EventArgs e)
{
    Accounts.CheckLogin();
    
this.UserName.Text = Session["UserName"].ToString();
}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-608417/,如需轉載,請註明出處,否則將追究法律責任。

相關文章