自定义对象 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 函数上),我想在标签中显示插入结果。以下顺序的操作说明了这一点:

  1. Select valid 包含要上传数据的文件 -> 单击上传 -> 发生回传并且 ViewState/Session 变量为 null
  2. Select 要上传的文件无效 -> 点击上传 -> 发生回发并且 ViewState/Session 变量读取 true
  3. 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)

通过跟踪这些面包屑,您将很快识别出页面生命周期的进展顺序。