我可以保存回发状态并恢复它吗

本文关键字:恢复 状态 保存 我可以 | 更新日期: 2023-09-27 18:27:34

假设在单击asp:button后,我想存储实际的"视图",每个控制器都有选定的值,比如asp:checkbox,或者用户在inputbox上插入的输入。

然后,我换了一个页面,用一个链接,比如"回到上一页"。我想在离开之前"恢复"旧的实际形式。

使用.NET有可能吗?或者我需要在变量中实现所有控件并将它们放在会话中?

我可以保存回发状态并恢复它吗

有几种方法可以在ASP.NET页面之间持久化或传递值。

看看这里了解更多信息。

因为你已经提到你有"大量"的控制来存储和恢复,我试图找到一种方法来自动化这个过程。

以下是我的方法,它使用Session作为存储来持久化IPostBackDataHandler类型的所有控件的值。没有经过真正的测试,但希望无论如何都有帮助。

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

以下是重定向到另一个页面的页面中的示例实现:

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

请注意,它在Page_Load/Page_PreRender上以隐含方式加载和保存。因此,必须在Page_PreInit中创建FormStorage实例。

如果要以编程方式更改Page_Load之后的值,则需要手动调用storage.saveForm()(例如在Page_PreRender中)以确保覆盖这些值,因为FormStorage将自动将所有回发数据保存在Page_Load中。

编辑:sh4nx0r的history.go方法可能更好,因为它更具可扩展性。我的方法使用会话,不适合拥有大量(可能)用户的互联网应用程序。

我的一个(小)优点是,即使禁用javascript,它也能工作。一个更大的优点是,您可以控制重定向到要重定向的页面。您甚至可以跨多个重定向恢复值。

您不需要会话就可以做到这一点。只需使用JavaScript。

假设您有两个页面Page1.aspx和Page2.aspx。Page1.aspx上有文本框、复选框和单选按钮,还有一个"提交"按钮。点击按钮进入Page2.aspx.

只要在Page2.aspx上有一个按钮"返回上一页",点击它就会进入Page1.aspx,所有这些值仍然存在。为此,请在Page2.aspx page_load事件上添加此行

protected void Page_Load(object sender, EventArgs e)
{
 btnBackButton.Attributes.Add("onClick", "javascript:window.history.go(-1);return false;");
}