c# - 我可以保存回发状态并恢复吗?

标签 c# asp.net asp.net-3.5

假设在点击asp:button 后,我想存储实际的“ View ”,为每个 Controller 选择值,如 asp:checkbox,或由输入框上的用户。

然后,我更改页面,使用诸如“返回上一页”之类的链接。我希望在离开之前“恢复”旧的实际形式。

.NET 可以吗?或者我需要在变量中实现所有控件并将它们放入 session 中?

最佳答案

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

看看here了解更多信息。

因为您已经提到您有“大量”控件来存储和恢复,所以我试图找到一种方法来自动化此过程。

这是我的方法,它使用 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 方法可能更好,因为它更具可扩展性。我的方法使用 session ,不适合具有大量(可能)用户的互联网应用程序。

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

关于c# - 我可以保存回发状态并恢复吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9668905/

相关文章:

c# - ASP.NET Core (HttpSys) 路由在本地工作,但在部署时不工作

c# - 如何比较两个无序列表框之间的项目

c# - 将 ToShortDateString 格式化为 dd/MM/yyyy

c# - 在 ASP.NET MVC 和 Azure AD 中创建自定义用户角色

c# - 列表框内的复选框

.net - 在 asp.net 3.5 中将 List<string> 绑定(bind)到 Listview

c# - "Cloning" Entity Framework 中的 EntityConnections 和 ObjectContext

c# - 在 C# 中将 HTML 写入 WebBrowser 的正确方法是什么?

c# - 匿名类的通用列表

c# - IE 7 错误? - 下载文件时提示保存/打开 - c# asp.net 3.5