自定义对象 class 不与 ViewState 保持一致
Custom object class not persisting with ViewState
我在我的命名空间中有一个名为 results 的私有可序列化自定义对象 class,我用它来存储文件 upload/server 推送的结果:
namespace DataUploadTool
{
enum errors {none, format, data, type, unk};
public partial class uploader : System.Web.UI.Page
{
private results res;
[Serializable]
private class results
{
public string errLogPath { get; set; }
public string fileName { get; set; }
public int errorType { get; set; }
public int rowsImported { get; set; }
public DateTime startTime { get; set; }
public DateTime endTime { get; set; }
}
...
}
我在代码中以标准方式设置对象的成员,即
res.fileName = fileUpload.FileName;
等
我将对象添加到 ViewState:
void Page_PreRender(object sender, EventArgs e)
{
ViewState.Add("resultsLog", res);
}
然后我尝试像这样检索它:
protected void Page_Load(object sender, EventArgs e)
{
res = new results();
if (IsPostBack)
{
if (ViewState["resultsLog"] != null)
{
results test;
test = (results)ViewState["resultslog"];
error.Text = test.rowsImported.ToString();
}
else // Do things
}
}
问题是我一直在行 error.Text = test.rowsImported.ToString();
上收到 nullReferenceException。
Visual Studio 中的内置数据可视化工具告诉我 test 在从 ViewState 检索它的行之后为 null,这不会产生任何完全没有意义,因为它被 if 语句确定为不为空!我完全不知道这是怎么发生的,为什么会发生。
感谢任何帮助!
我知道出了什么问题。
PostBack 发生在 ViewState 保存之前,因为在此之前调用了我的数据库填充函数。
如果您遇到 ViewState/Session 变量为 null 的问题, 第一次回发 但后续回发包含来自 先前请求的变量,这就是正在发生的事情。
澄清:假设每次插入数据库后(发生在 button_onClick 函数上),我想在标签中显示插入结果。以下顺序的操作说明了这一点:
- Select valid 包含要上传数据的文件 -> 单击上传 -> 发生回传并且 ViewState/Session 变量为 null
- Select 要上传的文件无效 -> 点击上传 -> 发生回发并且 ViewState/Session 变量读取 true
- Select valid 要上传的文件 -> 单击上传 -> 发生回发并且 ViewState/Session 变量读取 false
如您所见,更新后的变量对后续回发可见。
基本上,我根本不需要使用 ViewState 或 Session。我可以在 onClick 函数末尾对对象数据进行操作,因为此时回发已经发生。
TL;DR:
如果您遇到 ViewState 或 Session variables/objects 不持久存在的问题,或者遇到奇怪的 "one-off" 逻辑错误,则在涉及的每一行代码处添加断点:
- View/Session state setting/getting
- Function declarations which call these getters/setters
- Any function which accesses database data (reading/writing)
通过跟踪这些面包屑,您将很快识别出页面生命周期的进展顺序。
我在我的命名空间中有一个名为 results 的私有可序列化自定义对象 class,我用它来存储文件 upload/server 推送的结果:
namespace DataUploadTool
{
enum errors {none, format, data, type, unk};
public partial class uploader : System.Web.UI.Page
{
private results res;
[Serializable]
private class results
{
public string errLogPath { get; set; }
public string fileName { get; set; }
public int errorType { get; set; }
public int rowsImported { get; set; }
public DateTime startTime { get; set; }
public DateTime endTime { get; set; }
}
...
}
我在代码中以标准方式设置对象的成员,即
res.fileName = fileUpload.FileName;
等
我将对象添加到 ViewState:
void Page_PreRender(object sender, EventArgs e)
{
ViewState.Add("resultsLog", res);
}
然后我尝试像这样检索它:
protected void Page_Load(object sender, EventArgs e)
{
res = new results();
if (IsPostBack)
{
if (ViewState["resultsLog"] != null)
{
results test;
test = (results)ViewState["resultslog"];
error.Text = test.rowsImported.ToString();
}
else // Do things
}
}
问题是我一直在行 error.Text = test.rowsImported.ToString();
上收到 nullReferenceException。
Visual Studio 中的内置数据可视化工具告诉我 test 在从 ViewState 检索它的行之后为 null,这不会产生任何完全没有意义,因为它被 if 语句确定为不为空!我完全不知道这是怎么发生的,为什么会发生。
感谢任何帮助!
我知道出了什么问题。
PostBack 发生在 ViewState 保存之前,因为在此之前调用了我的数据库填充函数。
如果您遇到 ViewState/Session 变量为 null 的问题, 第一次回发 但后续回发包含来自 先前请求的变量,这就是正在发生的事情。
澄清:假设每次插入数据库后(发生在 button_onClick 函数上),我想在标签中显示插入结果。以下顺序的操作说明了这一点:
- Select valid 包含要上传数据的文件 -> 单击上传 -> 发生回传并且 ViewState/Session 变量为 null
- Select 要上传的文件无效 -> 点击上传 -> 发生回发并且 ViewState/Session 变量读取 true
- Select valid 要上传的文件 -> 单击上传 -> 发生回发并且 ViewState/Session 变量读取 false
如您所见,更新后的变量对后续回发可见。
基本上,我根本不需要使用 ViewState 或 Session。我可以在 onClick 函数末尾对对象数据进行操作,因为此时回发已经发生。
TL;DR: 如果您遇到 ViewState 或 Session variables/objects 不持久存在的问题,或者遇到奇怪的 "one-off" 逻辑错误,则在涉及的每一行代码处添加断点:
- View/Session state setting/getting
- Function declarations which call these getters/setters
- Any function which accesses database data (reading/writing)
通过跟踪这些面包屑,您将很快识别出页面生命周期的进展顺序。