为什么我上回发失去对象引用?
-
21-09-2019 - |
题
我开发一个asp.net(3.5)应用和我困惑与回发的行为。
考虑以下情形:我有一个Web用户控制,基本上是一种形式。然而每个表单字段本身是一种网络的用户控制。
在保存按钮的点击事件中,我通过我的表单的所有控件和迭代我检索字段值和指我保存价值的数据库字段的字段名。
在单击事件触发回发,这是我访问控制回发期间,这里是可笑的:数据库字段属性值已经成为空!任何人都可以棚光在这里?
下面是一些基本的代码:
[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...");
}
}
解决方案
记住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; }
}
其他提示
首先猜测是BindText()不应该在的Page_Load,但在Page_Init,所以控制状态将被保存。
@大卫巴萨拉布,这是不正确的据我所知,并且只有在情况NET 1.1,在.NET2最多,这是全部由框架处理,如果你做的所有神奇的东西在Init。
您的问题是,“ProfileField”是不可用的回发了吧?
的解决方案是存储用于在ViewState中的值(而不是一个自动实现的属性)。不这样做,也不会是可在回发。
不隶属于 StackOverflow