SqlDataSource的OnInserted事件过早触发了。

3
我有一个SqlDataSource,它有一个OnInserted处理程序。该处理程序会发送一封电子邮件,并从插入的记录中获取数据,包括其ID(一个输出参数)。
昨天,我收到了一个时间戳为下午4:00的处理程序发送的电子邮件,比SQL中提交记录的时间戳早20分钟。如果您认为这是Web/SQL/Exchange服务器之间的机器时间差异...我已经排除了这种可能性。插入是通过存储过程执行的,它会在多个表中插入记录。所有这些表都具有下午4:20的时间戳。
此外,电子邮件包含一个不准确的ID,与记录没有在发送电子邮件时提交一致。
问题是,在SQL记录提交之前,SqlDataSource的OnInserted处理程序如何发送电子邮件?
protected void On_Inserted(object sender, SqlDataSourceStatusEventArgs e)
{
    try
    {
        //GET THE RECORD ID
        String RecordID = String.Empty;
        RecordID = e.Command.Parameters["@RecordID"].Value != null ? e.Command.Parameters["@RecordID"].Value.ToString() : String.Empty;

        //SEND THE EMAIL
        SmtpClient smtp = new SmtpClient("SmtpHere",##);
        MailMessage email = new MailMessage();
        email.From = new MailAddress("FromAddressHere");
        email.To.Add("ToAddressHere")
        email.Subject = "Example Email";
        email.Body = "The record #" + RecordID + " was just added.";
        smtp.Send(email);
        smtp = null;
        email.Dispose();

        //GO TO THE PAGE WITH THE NEW RECORD ID
        HttpContext.Current.Response.Redirect("~/Page.aspx?RecordID=" + RecordID, false);
    }
    catch (Exception ex)
    {
        //HANDLE EXCEPTION
    }
}

1
您需要提供您的事件代码。 - NotMe
1
我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
1个回答

3
我猜测你的电子邮件代码(在SqlDataSource.Inserted事件中)没有检查SqlDataSourceStatusEventArgs.AffectedRows属性,以确保实际插入了一行:
protected void SqlDataSource1_OnInserted(Object source, SqlDataSourceStatusEventArgs e) 
{
    if (e.AffectedRows > 0)
    {
        // Send e-mail
    }
    else
    {
        // For some reason, the insert didn't happen.  Check for exceptions
        string errorMessage = e.Exception.InnerException.Message;
        // Here you want to display this error to the user, or log it, or something
    }
}

我想发生的事情如下:
1.电子邮件被发送,尽管记录实际上尚未插入。 2.20分钟后,另一个插入操作成功。 另一封电子邮件被生成,行被插入等。
这种错误很可能在一段时间内不被注意到,因为您的插入操作失败的概率可能相对较低。

那么,如果OnInserted不等待Insert语句被提交,那么触发OnInserted的是什么?我的理解是,在Insert语句完成后,OnInserted才会触发。来自msdn的说明:“在SqlDataSource控件完成插入操作后引发Inserted事件。” http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasourceview.oninserted(v=vs.80).aspx - s15199d
@s15199d 对,这是令人困惑的部分。从 SqlDataSource 的角度来看,插入操作已经完成(在它构造了一个 SQL 语句、将其发送到数据库并获得某种响应的意义上)。它没有说“在数据库上成功执行插入操作之后”。这就是为什么它们会向您发送 ExceptionExceptionHandled 属性 - 开发人员需要决定如何处理它们。 - Josh Darnell
谢谢@jadarnel!你的回答非常准确。 - s15199d
@s15199d 很高兴我能帮你。这个问题我之前也遇到过 =) - Josh Darnell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接