2010-06-11 49 views
21

我在頁面的viewstate中存儲了一個對象。現在,當我訪問usercontrol上的相同視圖對象時,它顯示爲空。我甚至嘗試在usercontrol和page中使用相同的名稱創建相同的viewstate。兩者具有不同的值。爲什麼我無法訪問usercontrol中的頁面viewstate?

我知道viewstate是一個受保護的屬性。這個東西是如何在上面的scenerio中實現的,或者是否有任何其他原因導致這種行爲。

編輯:

用戶控件存在於頁面的標記。我沒有動態加載它。

我有一個頁面EditFacilityworkType.aspx。在頁面上我有一個用戶控件FacilityWorkTypeDetails.aspx(FacilityWorkTypeDetails1)。在這個usercontrol裏面我有一個用戶控件Workflow.aspx(Workflow1)

Page_Load()of Page 我正在檢索頁面page_load()上的workflowdetails。

FacilityWorktype facilityWorkType = facilityDetails.GetFacilityWorktypeDetail(SessionHelper.FacilityWorkTypeID); 
ViewState["WorkFlow"] = facilityWorkType.FacilityWorkTypeWorkFlow 

Inside usercontrol FacilityWorkTypeDetails.aspx。我有一個屬性

public FacilityWorktype FacilityWorkTypeDetails 
{ 
    get 
    { 
     #region Fill FacilityWorktype 
     return GetEntityFromControl(); 
     #endregion 
    } 
    set 
    { 
     PopulateControls(value); 
    } 
} 

現在我在頁面的頁面加載設置該屬性

FacilityWorkTypeDetails1.FacilityWorkTypeDetails = facilityWorkType; 

裏面Workflow.aspx,我有一個屬性

/// <summary> 
/// Property to fill entity object from controls on this page 
/// </summary> 
public WorkFlow WorkFlowDetails 
{ 
    get 
    { 
     return GetEntityFromControls(); 
    } 
    set 
    {    
     BindTranscriptionMethodDDL(ddlTranscMethod); 
     PopulateControls(value); 
    } 
} 

現在PopulateControls()FacilityWorkTypeDetails1的,我正在設置工作流程的屬性1

private void PopulateControls(Facility Worktype值) {

Workflow1.WorkFlowDetails = value.FacilityWorkTypeWorkFlow; 
} 

現在,當我從

private WorkFlow GetEntityFromControls() 
{ 
    WorkFlow workFlow = (ViewState["WorkFlow"] as WorkFlow) ?? new WorkFlow(); 
    //workFlow is null 

} 

檢索值那麼現在這個函數內部工作流程爲空。我想問,爲什麼當我在頁面中設置viewstate時爲空。

+2

如何(或其中;後面的代碼)你「在視圖狀態頁面上存儲的對象」?如果你需要存儲「某處」「某處」以便稍後從「其他地方」檢索它,那麼你似乎在尋找會話功能而不是視圖狀態......而且你不能「創建相同的視圖狀態」:你是什麼意思; viewstate由ASP.NET自動維護(創建等)?我認爲你在這裏混合了一些東西(最可能是視圖狀態和會話)。如果你描述你正在努力達到的目標,這可能會有所幫助。 – scherand 2010-06-11 08:22:55

+0

您是否檢查您的頁面或web.config中的enableviewstate是否設置爲false? – mamoo 2010-06-11 08:24:15

+2

我還沒有完全理解你想要達到的目標。 **但我想我可以回答你爲什麼'workFlow'爲null **的問題。 「問題」是'GetEntityFromControls()'在「Workflow.aspx」內部(而不是'Workflow.ascx'可能?)。所以你訪問的'ViewState'對象不是'Page'中的一個。所以嚴格來說,'ViewState [「WorkFlow」]'不是空的,但沒有定義/可用(在'ViewState'對象中沒有稱爲「WorkFlow」的條目,因爲沒有人在其中放置過)。 – scherand 2010-06-11 09:10:31

回答

36

Scherand在這裏非常正確。我想補充一下他帶給桌上的東西。

從System.Web.UI.Control派生的每個控件都具有ViewState屬性。這個屬性是一個StateBag集合。 Control的每個實例都有自己的ViewState StateBag,所以Scherand提到過,ViewState對於控件來說是唯一的。當頁面被渲染時,頁面的整個Control樹被迭代,所有的ViewState集合被合併到一個樹狀結構中,並且最終的結構被序列化爲一個字符串並呈現給頁面。

由於ViewState屬性被標記爲受保護,因此無法使用反射從用戶控件訪問Page的ViewState。

但是,誠實地說,您應該放棄使用ViewState作爲數據存儲介質。這裏有一些原因:

  1. ViewState被渲染並輸出到客戶端瀏覽器。維護集合中的數據對象會擴大頁面的輸出。
  2. 除非在ViewState上啓用了加密,否則呈現給客戶端瀏覽器的編碼字符串可以手動解碼,任何人都可以訪問數據對象的內容。這是一個相當重要的安全漏洞。

這聽起來像是你想要做的就是在頁面和用戶控件之間共享數據。在控件之間共享數據的最佳方式是使用「Items」集合(這是HttpContext類的屬性)。集合是一個Hashtable,可以從你的頁面和用戶控件,像這樣來訪問:

Context.Items["Workflow"] = workflowInstance; 

使用這種技術的最好的部分是,它不產生任何額外的開銷或臃腫的頁面輸出。 Items集合存在於單個HTTP請求的上下文中。這意味着當您的請求完成並且您的頁面輸出已呈現給客戶端瀏覽器時,Items集合將從服務器內存中清除。它是ASP.NET中臨時數據存儲的理想媒介。

現在,如果您希望數據對象保持不僅僅是當前請求的可訪問性,您最好將它存儲在Session中。

+0

感謝這個答案,這正是我一直在尋找的! – Peter 2010-11-12 11:08:23

+0

在回發上怎麼樣?我的代碼:Context.Items [「dtCountryRecords」] = dtCountry;但是當我第一次訪問它時,它給了我正確的值,但是在回發函數中,在usercontrol pageload事件中返回null。 – user1254053 2015-05-14 11:34:54

+0

「Items」集合無法在Postback中生存。請看上面我回答的最後一段,以獲得更多細節。 如果你想要一個能夠存活的媒體回傳,你需要看看「Session」或「Cache」集合。 – 2015-06-01 16:22:22

1

在回發上您是否創建了控件?如果後面的代碼沒有創建ctrl,那麼它不會知道它。

僅當這是生成的控件時才適用。您可能需要發佈代碼和更多信息才能獲得答案。

Viewstate是一個怪物,這就是爲什麼我們很多人都去MVC。

3

我還是不會在這裏討論一切(參見上面的評論)。但我很肯定你是誤解ViewState

ViewState是每控制,而不是每個請求或會話或任何。

在你的例子中,考慮一些其他的控件(例如一個標準的ASP.NET控件),由於某種原因決定把一個名字爲WorkFlow的東西放到viewstate中。如果你試圖做的事情會起作用,這個對象會覆蓋你的(或者反過來,你的對象會被另一個覆蓋)。

或者我錯過了什麼?

也許閱讀TRULY Understanding ViewState可以幫助您瞭解視圖狀態是什麼/它是如何工作的(是的,我非常喜歡這篇文章,這就是爲什麼我一直在發佈該鏈接)。

1

page viewstate是usercontrol可以訪問的視圖狀態的不同狀態包。每個控件都有自己的私有視圖狀態。所以你不能直接從usercontrol代碼隱藏中訪問頁面viewstate。

,你可以用公開的屬性或方法視圖狀態值,然後調用這些屬性/方法

相關問題