为什么我上回发失去对象引用? [英] Why am I losing object references on the postback?

查看:103
本文介绍了为什么我上回发失去对象引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个asp.net(3.5)应用程序,我百思不得其解的回发的行为。

考虑以下情形:我有一个Web用户控件,基本上是一种形式。然而,每个表单字段本身就是一个Web用户控件。

在保存按钮的点击事件中,我通过我的表单的所有控件和迭代我检索字段值,这指的是我保存价值的数据库字段的字段名称。

单击事件触发回发,这是我访问控制回发期间,这里是有趣的事:为数据库中的字段属性值已经成为空!任何人都可以流下了光吗?

下面是一些基本的code:

  [Serializable接口]
公共部分类UserProfileForm:CustomIntranetWebappUserControl
{
    保护覆盖无效的OnInit(EventArgs的发送)
    {
        // AutoEventWireup设置为false
        负载+ = Page_Load中;
        CancelLinkBut​​ton.Click + = CancelButtonClickEvent;
        SaveLinkBut​​ton.Click + = SaveButtonClickEvent;
        base.OnInit(E);
    }    私人无效SaveButtonClickEvent(对象发件人,EventArgs的发送)
    {
        VisitFormFields();
    }    私人无效VisitFormFields()
    {
        VAR userProfileVisitor =新UserProfileVisitor();        的foreach(在控制功控制)
        {
            如果(控制FormFieldUserControl)
            {
                VAR formField =(FormFieldUserControl)控制;
                formField.Visit(userProfileVisitor);
            }
        }
        userProfileVisitor.Save();
    }    保护无效的Page_Load(对象发件人,EventArgs的发送)
    {
        如果(!的IsPostBack)
        {
            BindText();
        }
    }    私人无效BindText()
    {
        LastNameFormLine.LabelText =的String.Format({0},HomePage.Localize(姓));
        LastNameFormLine.InputValue = UserProfile.LastName;
        LastNameFormLine.IsMandatoryField = TRUE;
        LastNameFormLine.IsMultilineField = FALSE;
        LastNameFormLine.ProfileField =UserProfile.LastName;
        // ...该方法的其余部分是完全一样了上述4个行。
    }
}[Serializable接口]
公共抽象类FormFieldUserControl:CustomIntranetWebappUserControl
{
    公共字符串ProfileField {搞定;组; }
    公共抽象无效访问(UserProfileVisitor userProfileVisitor);
}
[Serializable接口]
公共部分类FormLineTextBox:FormFieldUserControl
{
// ...无关code删除...    公共覆盖无效访问(UserProfileVisitor userProfileVisitor)
    {
        如果(userProfileVisitor == NULL)
        {
            Log.Error(UserProfileVisitor不为字段定义:+ ProfileField);
            返回;
        }
        userProfileVisitor.Visit(本);
    }
}[Serializable接口]
公共类UserProfileVisitor
{    公共无效访问(FormLineTextBox formLine)
    {
        // formLine.ProfileField的值为null!
        Log.Debug(的String.Format(保存表单字段类型{1}与文件字段[{0}]和值{2},formLine.ProfileField,formLine.GetType()名称,formLine.InputValue));
    }    // ...去除无关code ...    公共无效保存()
    {
        Log.Debug(触发保存操作...);
    }
}


解决方案

记住ASP.NET是无状态的。创建页面后,被破坏的任何属性已经呈现给浏览器。所以,你必须重新对每个岗位的物体后面或将它们存储在浏览,会话或应用程序状态。

当你做一个属性,你必须告诉它来保存它不会自动做的视图状态。这里是一个视图状态属性的一个样本。

 公共字符串SomePropertyAsString
{
    得到
    {
        如果(this.ViewState [SomePropertyAsString] == NULL)
            返回的String.Empty;        回报(字符串)this.ViewState [SomePropertyAsString];
    }
    集合{this.ViewState [SomePropertyAsString] =值; }
}公共MyCustomType OBJECTPROPERTY
{
    得到
    {
        如果(this.ViewState [OBJECTPROPERTY] == NULL)
            返回null;        回报(MyCustomType)this.ViewState [OBJECTPROPERTY];
    }
    集合{this.ViewState [OBJECTPROPERTY] =值; }
}

I am developing an asp.net (3.5) application and I am puzzled with the behavior of the postbacks.

Consider the following scenario: I have a web user control that is basically a form. However each form field is a web user control in itself.

In the click event of the save button I iterate through all controls in my form and I retrieve the field value and the field name that refers to the database field that I am saving the value to.

The click event triggers a postback and it is during the postback that I visit the controls and here is the funny thing: the property value for the database field has become null! Could anyone shed a light here?

Here is some basic code:

[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...");
    }
}

解决方案

Remember ASP.NET is stateless. Any properties created are destroyed after the page has been render to the browser. So you have to recreate objects on each post back or store them in View, Session, or Application State.

When you do a property you have to tell it to save the view state it does not do it automatically. Here is a sample of a view state property.

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; }
}

这篇关于为什么我上回发失去对象引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆