Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I save a postback status and restore it?

Suppose that, after a click on a asp:button, I'd like to store the actual "view", with selected value for each controllers, like asp:checkbox, or input inserted by users on inputbox.

Than, I change page, with a link such as "back to the previous page". I'd like so "restore" the old actual form, before leaving it.

Is it possible with .NET? Or I need to implements all controls in variables and put them in session?

like image 741
markzzz Avatar asked Dec 05 '25 05:12

markzzz


1 Answers

There are several ways how you can persist or pass values between ASP.NET pages.

Have a look here for more informations.

Because you've mentioned that you have "tons" of controls to store and restore, i've tried to find a way to automatize this process.

Here's my approach which uses Session as storage to persist all controls' values of type IPostBackDataHandler. Not really tested but hopefully helpful anyway.

using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

public class FormStorage
{
    private System.Web.UI.Page _page = null;

    public Dictionary<String, Dictionary<String, String>> storage
    {
        get { return (Dictionary<String, Dictionary<String, String>>)_page.Session["FormStorage"]; }
        set { _page.Session["FormStorage"] = value; }
    }

    public FormStorage(System.Web.UI.Page page)
    {
        _page = page;
        initHandler();
        if (this.storage == null)
        {
            this.storage = new Dictionary<String, Dictionary<String, String>>();
        }
        if(!this.storage.ContainsKey(_page.Request.Path))
            this.storage.Add(_page.Request.Path, new Dictionary<String, String>());
    }

    private void initHandler()
    {
        _page.Init += Init;
        _page.Load += Load;
    }

    private void Init(Object sender, EventArgs e)
    {
        loadForm();
    }

    private void Load(Object sender, EventArgs e)
    {
        saveForm();
    }

    private void loadForm()
    {
        var pageStorage = storage[_page.Request.Path];
        var e = pageStorage.GetEnumerator();
        while (e.MoveNext())
        {
            loadControl(e.Current.Key, e.Current.Value);
        }
    }

    private void loadControl(String ID, String value)
    {
        Control control = findControlRecursively(_page, ID);
        if (control != null)
        {
            setControlValue(control, value);
        }
    }

    private void setControlValue(Control control, String value)
    {
        if (control is ITextControl)
        {
            ITextControl txt = (ITextControl)control;
            txt.Text = value == null ? "" : value;
        }
        else if (control is ICheckBoxControl)
        {
            ICheckBoxControl chk = (ICheckBoxControl)control;
            chk.Checked = value != null;
        }
        else if (control is ListControl)
        {
            ListControl ddl = (ListControl)control;
            if (value == null)
                ddl.SelectedIndex = -1;
            else
                ddl.SelectedValue = value;
        }
    }

    public void saveForm()
    {
        saveControlRecursively(this._page);
    }

    private void saveControlRecursively(Control rootControl)
    {
        if (rootControl is IPostBackDataHandler)
        {
            var postBackData = _page.Request.Form[rootControl.ID];
            storage[_page.Request.Path][rootControl.ID] = postBackData;
        }

        if (rootControl.HasControls())
            foreach (Control subControl in rootControl.Controls)
                saveControlRecursively(subControl);
    }

    private static Control findControlRecursively(Control rootControl, String idToFind)
    {
        if (rootControl.ID == idToFind)
            return rootControl;

        foreach (Control subControl in rootControl.Controls)
        {
            Control controlToReturn = findControlRecursively(subControl, idToFind);
            if (controlToReturn != null)
            {
                return controlToReturn;
            }
        }
        return null;
    }
}

Here's an examplary implementation in a page that redirects to another page:

private FormStorage storage;

protected void Page_PreInit(object sender, EventArgs e)
{
    storage = new FormStorage(this);
}

protected void BtnRedirect_Click(object sender, EventArgs e)
{
    Response.Redirect("RedirectForm.aspx");
}

Note that it loads and saves implicitely on Page_Load/Page_PreRender. Therefor the FormStorage instance must be created in Page_PreInit.

If you want to change values after Page_Load programmatically, you need to call storage.saveForm() manually (for example in Page_PreRender) to ensure that these values are overridden, because FormStorage will auto-save all postback data in Page_Load.

Edit: The history.go approach of sh4nx0r is probably better since it's more scalable. My approach uses the Session and would not be appropriate for an internet-application with a huge amount of (possible) users.

One (small) advantage of mine is that it would work even when javascript is disabled. One larger advantage is that you can control to what page you want to redirect. You can even restore values across multiple redirects.

like image 85
Tim Schmelter Avatar answered Dec 07 '25 18:12

Tim Schmelter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!