Pergunta

Estou desenvolvendo um aplicativo ASP.NET (3.5) e estou intrigada com o comportamento dos postagens.

Considere o seguinte cenário: tenho um controle do usuário da Web que é basicamente um formulário. No entanto, cada campo de formulário é um controle do usuário da Web em si.

No evento de cliques do botão Salvar, Itreado através de todos os controles no meu formulário e recupero o valor do campo e o nome do campo que se refere ao campo do banco de dados para o qual estou salvando o valor.

O evento de cliques aciona um postback e é durante o postback que visito os controles e aqui está o engraçado: o valor da propriedade para o campo do banco de dados se tornou nulo! Alguém poderia lançar uma luz aqui?

Aqui está algum código básico:

[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...");
    }
}
Foi útil?

Solução

Lembre -se de que asp.net está apátrida. Quaisquer propriedades criadas são destruídas depois que a página foi renderizada ao navegador. Portanto, você deve recriar objetos em cada postagem ou armazená -los à vista, sessão ou estado de aplicação.

Quando você faz uma propriedade, você deve dizer para salvar o estado de visualização, não o faz automaticamente. Aqui está uma amostra de uma propriedade do estado de exibição.

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

Outras dicas

O primeiro palpite seria que o bindText () não deveria estar em Page_load, mas em Page_init, para que o estado de controle seja salvo.

@David Basarab, isso não é verdadeiro Afaik e foi apenas o caso no .NET 1.1, no .NET2 e isso é todo tratado pela estrutura se você fizer todas as coisas mágicas no init.

Seu problema é que o 'perfilfield' não está disponível no postback, certo?

A solução é armazenar o valor para o ViewState (em vez de uma propriedade implementada automaticamente). Sem isso, não estará disponível no postback.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top