2009-09-04 85 views
1

我正在開發一個asp.net(3.5)應用程序,我對回發的行爲感到困惑。爲什麼我在回發中丟失對象引用?

考慮以下情形:我有一個Web用戶控件,基本上是一種形式。但是每個表單域本身都是一個Web用戶控件。

在保存按鈕,我通過我的表單的所有控件迭代的單擊事件,我檢索字段值和指我保存價值的數據庫字段的字段名稱。

click事件觸發回發,這是我訪問控制回發期間,這裏是可笑的:數據庫字段屬性值已經成爲空!任何人都可以在這裏發光嗎?

下面是一些基本的代碼:

[Serializable] 
public partial class UserProfileForm : CustomIntranetWebappUserControl 
{ 
    protected override void OnInit(EventArgs e) 
    { 
     //AutoEventWireup is set to false 
     Load += Page_Load; 
     CancelLinkButton.Click += CancelButtonClickEvent; 
     SaveLinkButton.Click += SaveButtonClickEvent; 
     base.OnInit(e); 
    } 

    private void SaveButtonClickEvent(object sender, EventArgs e) 
    { 
     VisitFormFields(); 
    } 

    private void VisitFormFields() 
    { 
     var userProfileVisitor = new UserProfileVisitor(); 

     foreach (var control in Controls) 
     { 
      if (control is FormFieldUserControl) 
      { 
       var formField = (FormFieldUserControl) control; 
       formField.Visit(userProfileVisitor); 
      } 
     } 
     userProfileVisitor.Save(); 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      BindText(); 
     } 
    } 

    private void BindText() 
    { 
     LastNameFormLine.LabelText = string.Format("{0}:", HomePage.Localize("Last Name")); 
     LastNameFormLine.InputValue = UserProfile.LastName; 
     LastNameFormLine.IsMandatoryField = true; 
     LastNameFormLine.IsMultilineField = false; 
     LastNameFormLine.ProfileField = "UserProfile.LastName"; 
     //... the rest of this method is exactly like the 4 lines above. 
    } 
} 

[Serializable] 
public abstract class FormFieldUserControl : CustomIntranetWebappUserControl 
{ 
    public string ProfileField { get; set; } 
    public abstract void Visit(UserProfileVisitor userProfileVisitor); 
} 


[Serializable] 
public partial class FormLineTextBox : FormFieldUserControl 
{ 
//... irrelevant code removed... 

    public override void Visit(UserProfileVisitor userProfileVisitor) 
    { 
     if (userProfileVisitor == null) 
     { 
      Log.Error("UserProfileVisitor not defined for the field: " + ProfileField); 
      return; 
     } 
     userProfileVisitor.Visit(this); 
    } 
} 

[Serializable] 
public class UserProfileVisitor 
{ 

    public void Visit(FormLineTextBox formLine) 
    { 
     // The value of formLine.ProfileField is null!!! 
     Log.Debug(string.Format("Saving form field type {1} with profile field [{0}] and value {2}", formLine.ProfileField, formLine.GetType().Name, formLine.InputValue)); 
    } 

    // ... removing irrelevant code... 

    public void Save() 
    { 
     Log.Debug("Triggering the save operation..."); 
    } 
} 

回答

7

記住ASP.NET是無狀態的。在頁面呈現給瀏覽器後,任何創建的屬性都將被銷燬。因此,您必須在每個帖子後面重新創建對象,或將它們存儲在視圖,會話或應用程序狀態中。

當你做一個屬性,你必須告訴它來保存它不會自動做的視圖狀態。這是一個視圖狀態屬性的示例。

public string SomePropertyAsString 
{ 
    get 
    { 
     if (this.ViewState["SomePropertyAsString"] == null) 
      return string.Empty; 

     return (string)this.ViewState["SomePropertyAsString"]; 
    } 
    set { this.ViewState["SomePropertyAsString"] = value; } 
} 

public MyCustomType ObjectProperty 
{ 
    get 
    { 
     if (this.ViewState["ObjectProperty"] == null) 
      return null; 

     return (MyCustomType)this.ViewState["ObjectProperty"]; 
    } 
    set { this.ViewState["ObjectProperty"] = value; } 
} 
+0

我在.net中編碼,因爲最近。所以我還沒有完整的框架知識。 然而,關於你的答案,我認爲這是準確的視圖狀態的事情目的... – Pablo 2009-09-04 12:39:51

+0

請參閱如何必須保存項來查看狀態編輯。 – 2009-09-04 12:42:40

0

首先猜測是BindText()不應該在Page_Load中,但在Page_Init,所以控制狀態也被保存。

0

@大衛巴薩拉布,這是不正確AFAIK,並在NET 1.1才的情況下,.NET2最多,這是所有的框架,如果你做的初始化所有的魔法的東西處理。

+1

即使在框架的新版本中,我也不認爲它神奇地保留了屬性值。如果是這樣,我一直在寫更多的代碼比我必須:)你有一個參考呢? – 2009-09-04 12:44:00

+0

嘗試此操作,請將佔位符'Bla'添加到Webform中: protected void Page_Init(object sender,EventArgs e) { TextBox tb = new TextBox(); Button bt = new Button(); bt.Click + =(s,ev)=> bt.Text = tb.Text; (Tb); Bla.Controls.Add(tb); (bt); Bla.Controls.Add(bt); } 工程就像一個魅力。 – 2009-09-04 12:50:55

0

您的問題是'ProfileField'在Postback上不可用,對吧?

的解決方案是針對該值存儲在視圖狀態(而不是自動實現的屬性)。沒有這一點,它不會在回發中提供。

+0

有關使用ViewState的代碼,請查看David的編輯。 – 2009-09-04 12:44:45