Page_Load多次触发?

时间:2014-07-29 01:51:25

标签: c# asp.net c#-4.0

过去几天我们一直在处理一个错误,所以我们创建了一个小页面(快速和脏的编程,我提前道歉)连接到数据库,检查文档是否存在,并显示一些数据与该文件有关。如果存在异常,则会发送包含异常信息和一些日志数据的电子邮件。

这是代码的简化版本(以下简短说明):

namespace My.Namespace
{
   public partial class myClass : System.Web.UI.Page
   {
       private static SqlConnection conn = null;
       private static SqlCommand command1 = null;
       private static SqlCommand command2 = null;
       private static string log = "";

       protected void Page_Load(object sender, EventArgs e)
       {
           if (!Page.IsPostBack)
           {
               try
               {
                    log += "START\n";
                    string docId = Request.QueryString["docId"];

                    if (!String.IsNullOrEmpty(docName))
                    {
                        bool docExists = doesDocExist(docId);

                        if (docExists == true)
                        {
                            string docMetadata = getMetadata(docId);
                            Response.Write(docMetadata);
                        }
                    }
                    else 
                    {
                        // display error message
                    }
                }
                catch (sqlException sqlex) 
                {
                    // process exception
                    sendErrorMessage(sqlex.Message);
                }
                catch (Exception ex)
                {
                    // process exception
                    sendErrorMessage(ex.Message);
                }
            }
        }

        private static bool doesDocExist(string docId)
        {
            log += "In doesDocExist\n";
            bool docExists = false;

            try
            {
                // open db connection (conn)
                string cmd = String.Format("SELECT COUNT(*) FROM docs WHERE id='{0}'", docId);
                command1 = new SqlCommand(cmd, conn);
                conn.Open();
                var val = command1.ExecuteScalar();
                int numberOfRows = int.Parse(val.ToString());
                if (numberOfRows > 0) { docExists = true; }
            }
            finally
            {
                // close db connection (conn)
            }

            return docExists;
        }

        protected string getMetadata(string docId)
        {
            log += "In getMetadata\n";
            string docMetadata = "";

            try
            {
                // open db connection (conn)
                string cmd = String.Format("SELECT metadata FROM docs WHERE id='{0}'", docID);
                command2 = new SqlCommand(cmd, conn);
                conn.Open();

                SqlDataReader rReader = command2.ExecuteReader();
                if (rReader.HasRows)
                {
                    while (rReader.Read())
                    {
                        // process metadata
                        docMetadata += DOCMETADATA;
                    }
                }
            }

            return docMetadata;
        }

        public static void sendErrorMessage(string messageText)
        {
            HttpContext.Current.Response.Write(messageText);

            // Send string log via email
        }    
    }
}

我知道它太长了,所以这里有一个快速描述。我们有一个使用Page_Load方法的类和其他三种方法:

  • doesDocExists:返回一个bool值,指示文档ID是否在数据库中。
  • getMetadata:返回包含与文档相关的元数据的字符串。
  • sendErrorMessage:发送一封电子邮件,其中包含在页面中生成的日志。

Page_Load我们致电doesDocExists。如果返回的值为 true ,则会调用getMetadata并在屏幕上显示该值。如果有任何错误,则会将其记录在Page_Load中,并以电子邮件形式发送。

问题在于,如果出现错误,而不是收到包含日志的电子邮件(即:START - 在Function1 - In Function2中),日志会在电子邮件中显示100次(即:START - In Function1 - 在Function2中 - Start - 在Function1中 - 在Function2中 - START ...依此类推),好像Page_Load多次被触发一样。

由于PostBack,我们在线阅读(http://www.craigwardman.com/blog/index.php/2009/01/asp-net-multiple-page-load-problem/)。所以,我们添加了条件if (!Page.IsPostBack),但结果仍然相同。

有多少理由会多次触发Page_Load?或者是我们对日志变量和/或导致此行为的try / catch做错了吗?

3 个答案:

答案 0 :(得分:1)

日志可能很长,因为您将字符串日志声明为 static 。它需要是静态的吗?

答案 1 :(得分:1)

private static SqlConnection conn = null;
private static SqlCommand command1 = null;
private static SqlCommand command2 = null;
private static string log = "";

问题在于日志 Singleton 以及其他属性。

每当您访问该页面时,都会将文字附加到日志属性,该属性最终为START - In Function1 - In Function2 - Start - In Function1 - In Function2 - START... and so on

根据您的方案,您不需要在myClass中使用 Singleton

仅供参考: 由于我不知道您的其余代码,请确保实例化conn, command1, command2

答案 2 :(得分:0)

如果您的页面加载功能执行了两次,因为当您点击按钮或链接时可以回发,那么应该检查它并按下面的方式运行

        if (!IsPostBack)
        {
 try
               {
                    log += "START\n";
                    string docId = Request.QueryString["docId"];

                    if (!String.IsNullOrEmpty(docName))
                    {
                        bool docExists = doesDocExist(docId);

                        if (docExists == true)
                        {
                            string docMetadata = getMetadata(docId);
                            Response.Write(docMetadata);
                        }
                    }
                    else 
                    {
                        // display error message
                    }
                }
                catch (sqlException sqlex) 
                {
                    // process exception
                    sendErrorMessage(sqlex.Message);
                }
                catch (Exception ex)
                {
                    // process exception
                    sendErrorMessage(ex.Message);
                }
            }
        }