6
\$\begingroup\$

I was looking for advice, feedback and information on best practices when designing ASP.NET Web Forms in a .NET web application.

Allow me to post a sample of how I currently do things. I am omitting the ASPX page as it only has 2 textboxes and a button. PersonEntity validates, loads, and saves in this example. Real-world would have a "Person" business object that saves, loads.

The Codebehind file of an "Add / Edit" page:

public partial class PersonAddUpdate : System.Web.UI.Page
{
    public int PersonId 
    {
        get
        {
            int _personId = 0;
            if (Int32.TryParse(Request.QueryString["id"], out _personId))
            {
                return _personId;
            }
            else
            {
                return 0;
            }
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            if (PersonId != 0)
            {
                var person = GetPersonById(PersonId);

                if (person != null)
                {
                    BindFormToData(person);
                    ViewState.Add("PersonEntity", person);
                }
            }                
        }
    }

    protected bool BindDataToForm(PersonEntity person)
    {
        person.FirstName = txtFirstName.Text;
        person.Lastname = txtLastName.Text;

        ViewState.Add("PersonEntity", person);

        // internal entity validation
        return person.Validate();
    }

    protected void BindFormToData(PersonEntity person)
    {
        txtFirstName.Text = person.FirstName;
        txtLastName.Text = person.Lastname;
    }

    protected PersonEntity GetPersonById(int personId)
    {
        PersonEntity person = new PersonEntity();
        return person.LoadById(personId);
    }

    protected void btnSave_Click(object sender, EventArgs e)
    {
        if (!Page.IsValid)
        {
            return;
        }

        PersonEntity person;

        if (ViewState["PersonEntity"] == null)
        {
            person = new PersonEntity();
        }
        else
        {
            person = (PersonEntity)ViewState["PersonEntity"];
        }

        if (!BindDataToForm(person))
        {
            // failed entity validation
            return;
        }

        if (!person.Save())
        {
            // problem saving
            return;
        }
        else
        {
            Response.Redirect("PersonDetail.aspx?id=" + person.Id.ToString());
        }
    }
}

Workflow:

Page Load: Get the id from querystring. If a problem arises, return 0. No records in the system have a "0" id. Try to load data. If there's data, set the form values and add it to viewstate.

On Save: Stop if page is invalid. Create an uninitialized PersonEntity. If viewstate contains an entity, then form binding (gets form values) routine does not need new PersonEntity. If viewstate is null, then we are a new record.

Call BindDataToForm which gets form field values and returns false if it fails internal entity validation. Attempt Save and continue if OK.

Questions:

I've been using this pattern for a while now. Do you see anything I can do to improve it? I was trying to find samples of complete forms that handle Add / Edit, but I was unable to find ones that worked as good as this with ORM-generated code.

Any comments, advice, ideas, or questions?

I hope the code is simple to read and understand.

\$\endgroup\$

migrated from stackoverflow.com Aug 25 '11 at 15:20

This question came from our site for professional and enthusiast programmers.

2
\$\begingroup\$

This is my feedback, Please let me know if I am misinterpreting :

1) Storing the entire PersonEntity object in viewstate will have following problems

  • It will make viewstate heavy and thus make page load slower.
  • It may not represent the current state of the object.

You can store the personId, recreate personentity object and then call save. A lot more about viewstate here http://www.freshegg.com/blog/creating-lean-fast-web-pages-view-state_3377

2) You can make the LoadById method static

\$\endgroup\$
  • \$\begingroup\$ It does add to viewstate's length. There are many options (a custom state persistence store, compression, etc) to remedy this, if your data object is able to hold a lot of data. The current state of the object should be correct. If this is a new object (a create), it is not loaded into viewstate until form binding, right before the constructor is called. If this is an edit, we've loaded the object into viewstate and we retrieve and modify it with the binding routine. Thank you for your feedback. \$\endgroup\$ – D-Sect Oct 5 '11 at 12:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.