我有一个包含多个控件的页面,例如Checkboxlists和两个包含搜索结果的容器。
我被告知要保持此网站的持久性,因此用户可以在浏览我们的网站时从任何地方回来并找到已恢复的设置(阅读:框已经检查;结果仍然可用)
到目前为止,我已经尝试覆盖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上的Viewstate来检索它?
编辑: 以下是通过session [“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;
}
}
}
但是,如果我查看searchresult然后只是触发GET以返回初始页面,则所有存储的项目都无法正确呈现。
答案 0 :(得分:2)
根据这个:
因此用户可以在浏览我们的网站时从任何地方回来并找到已恢复的设置(阅读:框已经检查;结果仍然可用)
只有当您在同一页面上时,视图状态才有效。它用于记住回发中的页面状态。如果您导航到另一个页面,则上一页面视图状态将丢失。你无法改变这种行为。
您要找的是ASP.Net profiles
我只是回答一个相关的问题:
答案 1 :(得分:1)
您的方法存在一些困难。
当前的问题是您在__VIEWSTATE
方法中手动添加“SavePageStateToPersistenceMedium
”隐藏字段。这会导致在发送到浏览器的html页面中呈现两个空的隐藏字段。由于您要覆盖该方法,页面将自动发送一个空的此类字段。
但是,您的方法存在的一个更大问题是LoadPageStateFromPersistenceMedium
方法只有在检测到回发后才会被页面调用。
通常情况下,如果用户在您的网站(或其他某个网站)上做了其他事情,然后返回到您的网页,您的网页将被新加载(定期GET,因此它不是回发邮件)。因此,无论您为相关页面缓存了什么视图状态,都不会加载。
为了解决您的问题,我认为您不得不存储页面的整个视图状态,而是存储足够的信息来重新绑定/重新初始化页面上的控件。然后,当页面加载并且不是回发后,您可以在Page_Load
中获取已保存的状态并重新初始化页面。
要存储状态,您可以使用几种可能的状态容器中的任何一种,包括:
答案 2 :(得分:0)
最终解决方案非常简单。 我只需要一些控件的状态而不是整个页面,因为结果可能随时改变。
问题是,CheckBoxLists的数据源是在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();
}
}
}
亲切的问候