2013年9月4日 星期三

[轉貼] 總結跨頁傳值及我所遇到的問題

出處:http://www.cnblogs.com/mingxuan/archive/2008/11/06/1328272.html

    asp.net的跨頁傳遞很好用,相信大家對這些也在熟悉不過了。利用Querystring,Sessions,Cookies,Application這些基於web特性得很直接,這不是我所要強調得重點,我要說的是Asp.net 特有的方式跨網頁提交和Server.Transfer.然後說說我用跨網頁提交時所遇到的問題。
    1.Server.Transfer跨頁傳值
    Server.Transfer有兩種重載方式,(1)public void Transfer(string path, bool preserveForm),   (2)public void Transfer(string path). preserveForm表示告訴服務器是否保存用於描述源頁面值的Form,單個參數得重載形式preserveForm==true;
    這個參數很有用,當我們設置preserveForm==true時,我們其實可以直接通過Requet.Form取得源頁面表單得值,當然我們也可以使用PreviousPage取得值,但我認為前者更好,不需PreviousPage.FindControl("xxx")再進行類型轉換來取值。或許效率會高一點吧(沒測試過呵呵)。
  下面代碼示例兩者的差別

複製代碼
 1    源頁 2 
 3 protected void btPostBack_Click(object sender, EventArgs e)  4   {  5       Server.Transfer("~/TargetServerTransfer1.aspx",true);  6   }  7   protected void Button1_Click(object sender, EventArgs e)  8   {  9      Server.Transfer("~/TargetServerTransfer2.aspx",false); 10   }11 
12 目標頁13 
14 //TargetServerTransfer1.aspx
15 
16 protected void Page_Load(object sender, EventArgs e) 17   { 18       Response.Write(Request.Form["tbName"].ToString()); 19       if (PreviousPage != null20       { 21         TextBox bt=(TextBox)PreviousPage.FindControl("tbName"); 22         Response.Write(bt.Text); 23       } 24   }//這樣頁面會重複輸出源頁面TextBox,id=tbName的text屬性值。25 
26 //TargetServerTransfer2.aspx
27 
28 protected void Page_Load(object sender, EventArgs e) 29    { 30        //Response.Write(Request.Form["tbName"].ToString());//源頁面表單值沒被保存 不能這樣取值 
31        if (PreviousPage != null32        { 33 
34            TextBox bt = (TextBox)PreviousPage.FindControl("tbName"); 35            Response.Write(bt.Text); 36        } 37    }//text值只被輸出一次
38 
複製代碼

   為什麼Server.Transfer("~/TargetServerTransfer1.aspx",true),你就能採用Request.Form["tbName"],這是因為此時目標網頁再被訪問時,它使用的Response是從源網頁中取得的。但要注意的這種技術有一個副作用,在頁面進行重定向時,客戶端的URL仍然會保持源頁面的URL,這可能會使客戶認為他們所獲得的數據是源頁面產生的。當然,在大多數情況下,這不是問題,但是這將使調試變得更困難,而且這種方式只適合站內。
   2.跨網頁提交
   asp.net 2.0 中不但能過PostBack到本頁,而且可以PostBack到其他頁,這使跨網頁提交成為可能,但你必須在目標頁時指定他的源頁,以便取得目標頁中表單得值,可使用兩種方式
        (1)<%@ PreviousPageType VirtualPath="" %>
        (2)<%@ Reference VirtualPath="" %>
   兩者得主要區別在於使用Reference 指示符,它是將PreviousePage轉換成與源網頁相同得類型,具有強類型的特性。這樣你就可以通過智能提示來直接訪問。且你在目標頁中可以指定多個Reference ,PreviousPageType只能是一個否則造成編譯錯誤。下面為代碼示例了當使用跨提交時在目標訪問源頁得方式



 1 //使用Reference指示符
 2  if (PreviousPage != null) 3         { 4             if (PreviousPage.IsCrossPagePostBack) 5             { 6                 ReferenceSource refer = (ReferenceSource)PreviousPage; 7                 Response.Write(refer.getTextName); 8             } 9         }10  //使用PreviousPageType指示符
11  12  if (PreviousPage != null)13         {14             if (PreviousPage.IsCrossPagePostBack)15             {16                 TextBox bt = (TextBox)PreviousPage.FindControl("tbName");17                 Response.Write(bt.Text);18             }19         }

   注意:1.在源頁中指定使用Button 得PostBackUrl屬性指定你要跨頁提交的目標頁面。所有實現了System.Web.UI.WebControls.IbuttonControl接口的Web控件都有跨網頁提交的特性。
   2.當目標網頁訪問PreviousPage屬性時可以獲得源頁面的數據,ASP.NET運行時裝載並執行了源頁面。這將引發ProcessChildRequest事件的發生。而且,它還會引發Page_Init事件、Page_Load和任何其他的源頁面按鈕單擊事件。我們要避免由於不小心進行誤操作,所以最好通過IsCrossPostBack屬性來確認是否為一個跨網頁提交發生。
    實際上當你指定PostBackUrl為某個頁面時,ASP.NET框架將相應的控件綁定到一個新的叫WebForm_DoPostBackWithOptions的JavaScript函數,原形如下:
onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(「Button1」;, 「」, false, 「」, 「ReferenceTarget.aspx」;, false, false))"
    但這並不意味著一帆風順,客戶端可能不支持JavaScript,或者出現這樣得情況。WebForm_PostBackOptions未定義。我就 遇到這樣情況,打開他得源文件找到他得腳本引入地址
<script src="/WebSite1/WebResource.axd?d=3sBteobkrOuDvyCbOYcK5A2&amp;t=633617408508593750" type="text/javascript"></script>
   src中的代碼複製下來,放到瀏覽器地址中運行,出現 錯誤。
很少見。在網上找到了關於「指定的參數已超出有效值的範圍。參數名 utcDate」的解決方案大體說主要原因是程序集創建時間高於本機時間,且文中提出連個解決法案如下:
1、通過修改服務器系統時間,讓其比Assembly的時間要晚,則可以了
2、通過修改Assembly的創建時間,讓其早於服務器的時間,則可以了。
  根據文章中所提出得原因,我發現GAC中很多程序集得修改時間為11.8號(今天11.6),確實超前了,我也不知道事什麼原因造成的.但不管總樣問題還是解決了,我的解決方案是1,修改系統時間時期>11.8。但這本不是我得意圖,因為現在還沒有11.8號。對於解決方案二,我確實不知道怎麼修改Assembly的創建時間,呵呵,節省時間吧。我沒去深究了。有那個知道嗎?
 

沒有留言:

張貼留言