保持视图状态持久并按需检索它



我有一个包含多个控件的页面,例如复选框列表和两个保存搜索结果的容器。

我被告知要使这个网站持久化,这样用户就可以在浏览我们的网站时从任何地方回来,并发现它的设置恢复了(阅读:框 stll 选中;结果仍然可用)

到目前为止,我已经尝试覆盖SavePageStateToPersistenceMedium和LoadPageStateFromPersitenceMedium,但是当我单击页面上的按钮时,我总是遇到黄色的死机屏幕。

protected override void SavePageStateToPersistenceMedium(object viewState)
{
    string str = "VIEWSTATE_" + Request.UserHostAddress;
    Cache.Add(str, viewState, null, DateTime.Now.AddMinutes(Session.Timeout), TimeSpan.Zero, CacheItemPriority.Default, null);
    ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", str);
    ClientScript.RegisterHiddenField("__VIEWSTATE", "");
}
protected override object LoadPageStateFromPersistenceMedium()
{
    string str = Request.Form["__VIEWSTATE_KEY"];
    if (!str.StartsWith("VIEWSTATE_"))
    {
        throw new Exception("Invalid viewstate key:" + str);
    }
    return Cache[str];
}

我的代码是否有任何问题,我需要调用什么来检索Page_Load上的视图状态或Page_init来检索它?

编辑:这是通过会话["xyz"]解决它的方法

List<ListItem> selectItems = new List<ListItem>();
        foreach (ListItem item in CheckBoxListLevel.Items)
        {
            if (item.Selected)
                selectItems.Add(item);
        }
        Session.Add("SavedLevelItems", selectItems);

然后在Page_Load

   if (Session["SavedLevelItems"] != null)
    {
        List<ListItem> SessionList = (List<ListItem>)Session["SavedLevelItems"];
        foreach (var item in SessionList)
        {
            if (item.Selected)
            {
                CheckBoxListLevel.Items.FindByText(item.Text).Selected = item.Selected;
            }
        }
    }

但是,如果我查看搜索结果,然后只是触发 GET 以返回初始页面,则所有存储的项目都不会正确呈现。

根据这个:

因此,用户可以在浏览我们的网站时从任何地方返回并找到其设置已恢复(阅读:选中框 STLL ;结果仍然可用)

仅当您在同一页面上时,视图状态才有效。它用于跨回发记住页面状态。如果导航到另一个页面,则上一页视图状态将丢失。您无法更改此行为。

您正在寻找的是 ASP.Net 个人资料

我只回答一个相关的问题:

将 html 的状态保存到数据库

你的方法有几个困难。

直接的问题是您在SavePageStateToPersistenceMedium方法中手动添加" __VIEWSTATE"隐藏字段。这会导致两个空的隐藏字段呈现在发送到浏览器的 html 页面中。该页面将自动发送一个空的此类字段,因为您正在覆盖该方法。

但是您的方法的一个更大的问题是,LoadPageStateFromPersistenceMedium方法仅在检测到回发时由页面调用。

通常,如果用户一直在您的网站(或其他网站)上执行其他操作,然后返回您的页面,则您的页面将被重新加载(常规 GET,因此它不是回发)。因此,不会加载您为相关页面缓存的任何视图状态。

为了解决您的问题,我认为您不必存储页面的整个视图状态,而是只需存储足够的信息来重新绑定/重新初始化页面上的控件。然后,当页面加载且不是回发时,您可以在Page_Load中获取保存的状态并重新初始化页面。

若要存储状态,可以使用以下几种可能的状态容器中的任何一个,包括:

  • 会期
  • 缓存
  • SQL 服务器或其他自定义进程外存储区
  • 配置文件(就像Jupaol建议的那样,这至少是存储在sql数据库中的"默认"Asp.Net 提供程序)

最后,解决方案非常简单。我只需要一些控件的状态,而不是整个页面,因为结果可能随时更改。

问题是,复选框列表的数据源是在 aspx 文件中定义的。这导致当我尝试通过 Page_Load() 访问控件时没有加载任何项目。

因此,我将整个数据访问逻辑转移到文件背后的代码中,并包装在 if 语句中。如果合适的会话对象可用,则数据源是会话对象,否则从数据库中获取它。

 protected void fillEntrylevelList()
{
    using (OleDbConnection connection = new OleDbConnection(ConfigurationManager.ConnectionStrings["TestEnvironment"].ConnectionString))
    {
        string EntrylevelQuery = @"INSERT SQL STATEMENT HERE";
        OleDbCommand command = new OleDbCommand(EntrylevelQuery, connection);
        if (Session["SavedLevelItems"] != null)
            {
                CheckBoxListLevel.Items.Clear();
                List<ListItem> SessionList = (List<ListItem>)Session["SavedLevelItems"];
                foreach (var item in SessionList)
                {
                    try
                    {
                        CheckBoxListLevel.Items.Add(item);
                    }
                    catch { }
                }
            }
        else
        {
            connection.Open();
            CheckBoxListLevel.DataTextField = "bez_level";
            CheckBoxListLevel.DataValueField = "id_level";
            OleDbDataReader ListReader = command.ExecuteReader();
            CheckBoxListLevel.DataSource = ListReader;
            CheckBoxListLevel.DataBind();
            ListReader.Close(); ListReader.Dispose();
            GC.Collect();
        }
    }
}

亲切问候

最新更新