【问题标题】:Variables getting reinitialised when clicking on Button in C#在 C# 中单击按钮时变量被重新初始化
【发布时间】:2016-01-01 17:02:11
【问题描述】:

我正在制作在线表格。我一开始在我的代码中初始化了 4 个变量。当我选择一个下拉菜单时,会触发一个事件 (DropDownList4_SelectedIndexChanged),然后调用 Availability()。在这里,我的布尔变量 avail_bus 被分配了一个值。但是,当我单击提交按钮 (Button1_Click1) 时,变量 avail_bus 被重新初始化为 false。我对此进行了调试,发现在单击 Submit(Button1_Click1) 时,控件首先会转到页面中代码的顶部,即

public partial class Appform : System.Web.UI.Page
    {
        private bool isNotDup = true;
        private bool avail_bus ;
        private int max_capacity_bus;
        private int realAvailability;
}

然后转到 Button1_click1 。 我怎样才能防止这种情况发生?如果在调用可用性时avail_bus 的状态更改为true,则当我单击提交时它不应重新初始化为true。

下面是我的代码:

namespace eTransport
{
    public partial class Appform : System.Web.UI.Page
    {
        private bool isNotDup = true;
        private bool avail_bus ;
        private int max_capacity_bus;
        private int realAvailability;

        protected void Page_Load (object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                BindDropDown();


            }

        }

        //Method called when dropdown is selected in Bus Stop. It helps to populate Bus Number
        protected void DropDownList4_SelectedIndexChanged (object sender, EventArgs e)
        {

            AutoPopulateBusStop();
            Availability();

        }


        //Method to load drop down values in Bus Stop. These are populated from database
        protected void BindDropDown ()
        {
           //some code here
        }

        //Method to autopopulate Bus Number based on selection of Bus Stop. The mapping is in the database in the table named -> dropdownlist
        protected void AutoPopulateBusStop ()
        {
            //some code here
        }


        protected void Availability ()
        {
            string constr5 = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
            using (SqlConnection con5 = new SqlConnection(constr5))
            {
                try
                {

                    using (SqlCommand cmd5 = new SqlCommand("select count(*) from etms where BusNo='" + TextBox6.Text.ToString() + "'"))
                    {
                        cmd5.CommandType = CommandType.Text;
                        cmd5.Connection = con5;
                        con5.Open();
                        int capacity_from_db = Convert.ToInt16(cmd5.ExecuteScalar());
                        realAvailability = max_capacity_bus - capacity_from_db;

                        if (realAvailability > 0)
                        {
                            avail_bus = true;
                            TextBox2.Text = realAvailability.ToString() + " seats available ";
                            TextBox2.ForeColor = System.Drawing.ColorTranslator.FromHtml("#008000");

                        }
                        else
                        {

                            TextBox2.Text = "Seats Not available. Please choose another Stop";
                            TextBox2.ForeColor = System.Drawing.ColorTranslator.FromHtml("#ff1919");
                        }

                    }
                }
                catch (Exception ex)
                {
                    Response.Write(ex);
                }

            }

        }


        protected void Button1_Click1 (object sender, EventArgs e)
        {


            if (isNotDup)
            {
                if (avail_bus)
                {
                   // Submit the Form
                }
                else
                {
                    Label14.Text = "Bus Seats not available!";
                    Label15.Text = null;
                }
            }
        }



        protected void PhoneNumberValidatation (object source, ServerValidateEventArgs args)
        {

           //some code here



        }


         }
}

【问题讨论】:

  • 请分享按钮如何链接到事件Button1_Click
  • 你试过用静态的吗?
  • 静态不是最好的解决方案。使用视图状态。
  • @Rakin 你能解释一下原因吗?

标签: c# asp.net boolean


【解决方案1】:

这个问题有三种可能的解决方案。

Static - 这将创建一个可供所有页面访问的实例(全局)

private static avail_bus = true;

Session State - 这使您能够在用户导航时为用户存储和检索值。

// Get...
private bool avail_bus = (bool)Session["avail_bus"];
// Set
Session["avail_bus"] = true;

Control.ViewState - 获取状态信息字典,允许您跨同一页面的多个请求保存和恢复服务器控件的视图状态。

public bool avail_bus
{
    get { return  ViewState["avail_bus"] == null ? false : (bool)ViewState["avail_bus"]; }
    set { ViewState["avail_bus"] = value; }
}

【讨论】:

  • 永远不要在 asp.net 中使用静态变量,因为它们在会话和用户之间共享。
  • 没有。将服务器变量用于静态。用户静态字段的会话变量。其余部分的视图状态或隐藏字段。
  • 使用隐藏字段会是最好的解决方案吗?
  • @Azfar 使用 Session 而不是 Hidden Fields 更安全,因为 Session 只会显示一个随机 cookie。
  • @Azfar 是的,所以我建议改用 Session。
【解决方案2】:

您可以将可用性状态存储在一个隐藏的输入字段中,该字段稍后会在 Button1 点击事件上发布。

并且在button1点击事件中,而不是从变量访问avail值,而是从hiddenField的值访问它

另一个选项是在 button1 的点击事件中再次调用 Availability() 作为第一行,以便它在avail_bus 变量中设置正确的值

【讨论】:

    【解决方案3】:

    每次有对您的页面的请求时,都会创建该页面类的一个新实例来处理该请求。所以任何字段都会重新初始化。

    您可以在 ViewState 中存储一个值,以便在各种请求中记住一个值:

    namespace eTransport
    {
        public partial class Appform : System.Web.UI.Page
        {
    private bool isNotDup 
    {
       set { ViewState["isNotDup "] = value; }
       get 
       {
          if (ViewState["isNotDup "] == null)
             return true;
          return (bool )ViewState["isNotDup "];
       }
    }
    private bool avail_bus 
    {
       set { ViewState["avail_bus"] = value; }
       get 
       {
          if (ViewState["avail_bus"] == null)
             return true;
          return (bool )ViewState["avail_bus"];
       }
    }
    private int max_capacity_bus 
    {
       set { ViewState["max_capacity_bus "] = value; }
       get 
       {
          if (ViewState["max_capacity_bus "] == null)
             return 0;
          return (int)ViewState["max_capacity_bus "];
       }
    }
    private int realAvailability
    {
       set { ViewState["realAvailability"] = value; }
       get 
       {
          if (ViewState["realAvailability"] == null)
             return 0;
          return (int)ViewState["realAvailability"];
       }
    }
        protected void Page_Load (object sender, EventArgs e)
            {
                if (!this.IsPostBack)
                {
                    BindDropDown();
    
    
                }
    
            }
    
            //Method called when dropdown is selected in Bus Stop. It helps to populate Bus Number
            protected void DropDownList4_SelectedIndexChanged (object sender, EventArgs e)
            {
    
                AutoPopulateBusStop();
                Availability();
    
            }
    
    
            //Method to load drop down values in Bus Stop. These are populated from database
            protected void BindDropDown ()
            {
               //some code here
            }
    
            //Method to autopopulate Bus Number based on selection of Bus Stop. The mapping is in the database in the table named -> dropdownlist
            protected void AutoPopulateBusStop ()
            {
                //some code here
            }
    
    
            protected void Availability ()
            {
                string constr5 = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
                using (SqlConnection con5 = new SqlConnection(constr5))
                {
                    try
                    {
    
                        using (SqlCommand cmd5 = new SqlCommand("select count(*) from etms where BusNo='" + TextBox6.Text.ToString() + "'"))
                        {
                            cmd5.CommandType = CommandType.Text;
                            cmd5.Connection = con5;
                            con5.Open();
                            int capacity_from_db = Convert.ToInt16(cmd5.ExecuteScalar());
                            realAvailability = max_capacity_bus - capacity_from_db;
    
                            if (realAvailability > 0)
                            {
                                avail_bus = true;
                                TextBox2.Text = realAvailability.ToString() + " seats available ";
                                TextBox2.ForeColor = System.Drawing.ColorTranslator.FromHtml("#008000");
    
                            }
                            else
                            {
    
                                TextBox2.Text = "Seats Not available. Please choose another Stop";
                                TextBox2.ForeColor = System.Drawing.ColorTranslator.FromHtml("#ff1919");
                            }
    
                        }
                    }
                    catch (Exception ex)
                    {
                        Response.Write(ex);
                    }
    
                }
    
            }
    
    
            protected void Button1_Click1 (object sender, EventArgs e)
            {
    
    
                if (isNotDup)
                {
                    if (avail_bus)
                    {
                       // Submit the Form
                    }
                    else
                    {
                        Label14.Text = "Bus Seats not available!";
                        Label15.Text = null;
                    }
                }
            }
    
    
    
            protected void PhoneNumberValidatation (object source, ServerValidateEventArgs args)
            {
    
               //some code here
    
    
    
            }
    
    
             }
    }
    

    【讨论】:

    • ViewState 已经有它的缺点和很多东西要携带。为什么不简单地使用 HiddenField。这就是他们的目的。
    • @vnikhil 你确实意识到这也成为了视图状态的一部分?
    • 查看状态是安全的。隐藏字段不安全查看状态存储大量数据。隐藏字段将存储少量数据。
    • @hvd - 它们是分开的!否则,如果您在页面级别关闭视图状态,隐藏字段将不起作用。此外,一旦页面呈现并具有编码内容,ViewState 就会采用隐藏字段的形式,而 则不是这种情况,它以人类可读的格式向您显示存储的内容。请澄清我是否走错了方向。
    • @Rakin - 同意。 OP 只想存储 avail_bus 变量值。
    猜你喜欢
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多