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

时间:2016-07-12 08:44:15

标签: c# asp.net 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变量的最后一个案例。其他一切都很好。但是如果我没有重置,那么在我点击按钮后,另一个记录器会停止记录,因为buttonClicked保持为真。但是如果我实现了重置,则在Page_Load的开头将ViewState设置为false,因此失去所有含义,因为它会记录两次,一个用于按钮,另一个用于另一个记录器。我一直在拉着我的头发试图找出为什么这个案子似乎发生在if语句之前。

如果我在点击Page_Load时调试并从按钮单击事件开始步骤,则ViewState设置为false。如果我在else情况下注释掉该行,则在逐步调试时不会将其设置为false。发生了什么事?

1 个答案:

答案 0 :(得分:0)

单击按钮或触发任何其他回发时,会在实际事件绑定到例如按钮之前运行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.");
        }

    }