C# ASP.NET 在 ViewState 的帮助下记录到文件

C# ASP.NET Logging to file with help of ViewState

在我的页面上,我有一个触发事件并记录到 txt 文件的按钮。

void ButtonClick(object sender, EventArgs e)
    {
        // Stop/start service
        var button = (Button)sender;
        string machine = button.CommandArgument;
        string service;

        /*Do stuff */

        if (buttonClicked)
        {
            writeToLogFile("User " + HttpContext.Current.User.Identity.Name + " pressed the " + button.CommandName + " button on server " + machine + " with the services " + checkedBoxes(machine) + " checked.");
            ViewState["buttonClicked"] = buttonClicked;
        }
    }

该按钮更改了我的页面的状态。这种状态也可以从其他来源改变,所以我也记录下来。

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            prevStatus = new Dictionary<string, ServiceControllerStatus>();
            currStatus = new Dictionary<string, ServiceControllerStatus>();
            buttonClicked = false;
            ViewState["buttonClicked"] = false;
        }
        else
        {
            prevStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["prevStatus"];
            currStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["currStatus"];
            buttonClicked = (bool)ViewState["buttonClicked"];
            if (!buttonClicked)
            {
                foreach (var item in currStatus)
                {
                    ServiceControllerStatus oldStatus;
                    if (prevStatus.TryGetValue(item.Key, out oldStatus) && !(oldStatus == item.Value))
                    {
                        string[] split = item.Key.Split('_');
                        writeToLogFile("The service " + split[0] + " on server " + split[1] + " was changed to " + item.Value + " from another source.");
                    }
                }
            }
            else
            {
                ViewState["buttonClicked"] = false;
            }

但是当我点击我不想要的按钮时,这个日志也会记录下来。因此我必须在回发之间保持状态变量 buttonClicked

这里手头的问题是我重置 ViewState 变量的最后一个 else 案例。其他一切正常。但是,如果我没有此重置,则在我单击按钮后,另一个记录器将停止记录,因为 buttonClicked 保持为真。但是,如果我实施了重置,ViewState 在 Page_Load 开始时会被设置为 false,因此失去所有意义,因为它会记录两次,一次用于按钮,一次用于另一个记录器。我一直在绞尽脑汁想弄清楚为什么这个 else 案例似乎发生在 if 语句之前。

如果我在点击 Page_Load 后立即调试并退出按钮单击事件,则 ViewState 设置为 false。如果我在 else 情况下注释掉该行,则在逐步调试时它不会设置为 false。怎么回事?

当单击按钮或触发任何其他回发时,Page_Load 事件在实际事件绑定到按钮之前 运行。从 here 的页面生命周期中阅读更多内容。

所以问题是您尝试设置的 ViewState 值发生得太晚,无法在 Page_Load 中进行评估。

一种解决方案是简单地将日志记录逻辑放在单独的方法中,并在需要时调用。

示例:

 public partial class _Default : Page
    {      

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        private void Log()
        {            
            if (ViewState["prevStatus"] != null && ViewState["currStatus"] != null)
            {
                prevStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["prevStatus"];
                currStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["currStatus"];                

                foreach (var item in currStatus)
                {
                    ServiceControllerStatus oldStatus;
                    if (prevStatus.TryGetValue(item.Key, out oldStatus) && !(oldStatus == item.Value))
                    {
                        string[] split = item.Key.Split('_');
                        writeToLogFile("The service " + split[0] + " on server " + split[1] + " was changed to " + item.Value + " from another source.");
                    }
                }                
            }           
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Do stuff

            this.Log();
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            // Stop/start service
            var button = (Button)sender;
            string machine = button.CommandArgument;
            string service;

            /*Do stuff */
            writeToLogFile("User " + HttpContext.Current.User.Identity.Name + " pressed the " + button.CommandName + " button on server " + machine + " with the services " + checkedBoxes(machine) + " checked.");
        }

    }