我有一个包含多个控件的页面,例如复选框列表和两个保存搜索结果的容器。
我被告知要使这个网站持久化,这样用户就可以在浏览我们的网站时从任何地方回来,并发现它的设置恢复了(阅读:框 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();
}
}
}
亲切问候