GridView添加ImageButton后邮件无法发送,求适配代码方案
我原本有一段可发送包含GridView表格内容邮件的代码,运行正常。但在GridView最后一列添加ImageButton后,邮件无法发送。我尝试了一段格式化GridView的代码但无效,需要修改原代码,使其支持发送包含或不包含该图片按钮列的邮件。
原发送邮件代码
Protected Sub SendRequestMail() Dim tryCount As Integer = 5 Dim failed As Boolean = False Do Try failed = False Dim ToMailIDs As String ToMailIDs = LblRecipients.Text Using sw As New StringWriter() Using hw As New HtmlTextWriter(sw) GridView1.RenderControl(hw) Dim sr As New StringReader(sw.ToString()) Dim smtpSection As SmtpSection = CType(ConfigurationManager.GetSection("system.net/mailSettings/smtp"), SmtpSection) Dim mm As MailMessage = New MailMessage() mm.From = New MailAddress(smtpSection.From, "Notification") For i As Integer = 0 To ToMailIDs.Split(","c).Length - 1 mm.To.Add(New MailAddress(ToMailIDs.Split(","c)(i))) Next mm.ReplyTo = New MailAddress("xxxxx@xxxxx.xxx") mm.Subject = LblMrNumFull.Text & " | " & LblMrDate1x.Text & " | " & LblStorsName1.Text & " - Approval" mm.Body = LblMrNumFull.Text & " | " & LblMrDate1x.Text & " | " & LblStorsName1.Text mm.Body += sw.ToString() mm.Body += "<br />" mm.Body += "Thanking you" mm.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure mm.DeliveryNotificationOptions = DeliveryNotificationOptions.Delay mm.Headers.Add("Disposition-Notification-To", "yyyyyy@xxxxx.xxx") ' ----- webconfig mail start mm.IsBodyHtml = True Dim smtp As SmtpClient = New SmtpClient smtp.Host = smtpSection.Network.Host smtp.EnableSsl = smtpSection.Network.EnableSsl Dim networkCred As NetworkCredential = New NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password) smtp.UseDefaultCredentials = smtpSection.Network.DefaultCredentials smtp.Credentials = networkCred smtp.Port = smtpSection.Network.Port smtp.Send(mm) ' ----- webconfig mail end End Using End Using Catch ex As Exception failed = True tryCount = tryCount - 1 Finally Response.Redirect("~/abc/xyx.aspx?NewID=" & Request.QueryString("NewID")) End Try Loop While failed AndAlso tryCount > 0 End Sub
问题原因
当GridView包含服务器控件(如ImageButton)时,直接调用RenderControl会触发控件的视图状态、事件绑定等相关逻辑,容易抛出异常导致邮件发送中断。你之前尝试的代码仅处理了GridView样式,未解决控件渲染的核心问题。
方案1:隐藏ImageButton列后发送邮件
如果不需要在邮件中显示按钮,可临时隐藏该列,渲染完成后恢复列的可见性:
Protected Sub SendRequestMail() Dim tryCount As Integer = 5 Dim failed As Boolean = False ' 记录最后一列的原始可见状态 Dim originalColumnVisible As Boolean = GridView1.Columns(GridView1.Columns.Count - 1).Visible Do Try failed = False Dim ToMailIDs As String = LblRecipients.Text ' 临时隐藏包含ImageButton的最后一列 GridView1.Columns(GridView1.Columns.Count - 1).Visible = False Using sw As New StringWriter() Using hw As New HtmlTextWriter(sw) GridView1.RenderControl(hw) Dim gridHtml As String = sw.ToString() Dim smtpSection As SmtpSection = CType(ConfigurationManager.GetSection("system.net/mailSettings/smtp"), SmtpSection) Dim mm As MailMessage = New MailMessage() mm.From = New MailAddress(smtpSection.From, "Notification") ' 优化收件人处理,跳过空值 For Each mailId As String In ToMailIDs.Split(","c) If Not String.IsNullOrEmpty(mailId.Trim()) Then mm.To.Add(New MailAddress(mailId.Trim())) End If Next mm.ReplyTo = New MailAddress("xxxxx@xxxxx.xxx") mm.Subject = $"{LblMrNumFull.Text} | {LblMrDate1x.Text} | {LblStorsName1.Text} - Approval" mm.Body = $"{LblMrNumFull.Text} | {LblMrDate1x.Text} | {LblStorsName1.Text}<br/>" mm.Body += gridHtml mm.Body += "<br/>Thanking you" ' 合并通知选项,避免覆盖 mm.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure Or DeliveryNotificationOptions.Delay mm.Headers.Add("Disposition-Notification-To", "yyyyyy@xxxxx.xxx") mm.IsBodyHtml = True Using smtp As New SmtpClient smtp.Host = smtpSection.Network.Host smtp.EnableSsl = smtpSection.Network.EnableSsl Dim networkCred As New NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password) smtp.UseDefaultCredentials = smtpSection.Network.DefaultCredentials smtp.Credentials = networkCred smtp.Port = smtpSection.Network.Port smtp.Send(mm) End Using End Using End Using Catch ex As Exception failed = True tryCount -= 1 Finally ' 恢复列的原始可见状态 GridView1.Columns(GridView1.Columns.Count - 1).Visible = originalColumnVisible Response.Redirect($"~/abc/xyx.aspx?NewID={Request.QueryString("NewID")}") End Try Loop While failed AndAlso tryCount > 0 End Sub
方案2:保留按钮视觉效果(转为静态HTML图片)
如果需要在邮件中显示按钮的样子(无法点击),可将服务器端ImageButton替换为静态HTML图片标签:
Protected Sub SendRequestMail() Dim tryCount As Integer = 5 Dim failed As Boolean = False Do Try failed = False Dim ToMailIDs As String = LblRecipients.Text ' 将所有行的ImageButton替换为静态HTML图片 For Each row As GridViewRow In GridView1.Rows If row.RowType = DataControlRowType.DataRow Then Dim imgBtn As ImageButton = CType(row.Cells(GridView1.Columns.Count - 1).Controls(0), ImageButton) ' 清空控件并添加纯HTML图片 row.Cells(GridView1.Columns.Count - 1).Controls.Clear() row.Cells(GridView1.Columns.Count - 1).Text = $"<img src='{imgBtn.ImageUrl}' alt='{imgBtn.AlternateText}' style='border:none;' />" End If Next Using sw As New StringWriter() Using hw As New HtmlTextWriter(sw) GridView1.RenderControl(hw) Dim gridHtml As String = sw.ToString() Dim smtpSection As SmtpSection = CType(ConfigurationManager.GetSection("system.net/mailSettings/smtp"), SmtpSection) Dim mm As MailMessage = New MailMessage() mm.From = New MailAddress(smtpSection.From, "Notification") For Each mailId As String In ToMailIDs.Split(","c) If Not String.IsNullOrEmpty(mailId.Trim()) Then mm.To.Add(New MailAddress(mailId.Trim())) End If Next mm.ReplyTo = New MailAddress("xxxxx@xxxxx.xxx") mm.Subject = $"{LblMrNumFull.Text} | {LblMrDate1x.Text} | {LblStorsName1.Text} - Approval" mm.Body = $"{LblMrNumFull.Text} | {LblMrDate1x.Text} | {LblStorsName1.Text}<br/>" mm.Body += gridHtml mm.Body += "<br/>Thanking you" mm.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure Or DeliveryNotificationOptions.Delay mm.Headers.Add("Disposition-Notification-To", "yyyyyy@xxxxx.xxx") mm.IsBodyHtml = True Using smtp As New SmtpClient smtp.Host = smtpSection.Network.Host smtp.EnableSsl = smtpSection.Network.EnableSsl Dim networkCred As New NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password) smtp.UseDefaultCredentials = smtpSection.Network.DefaultCredentials smtp.Credentials = networkCred smtp.Port = smtpSection.Network.Port smtp.Send(mm) End Using End Using End Using Catch ex As Exception failed = True tryCount -= 1 Finally Response.Redirect($"~/abc/xyx.aspx?NewID={Request.QueryString("NewID")}") End Try Loop While failed AndAlso tryCount > 0 End Sub
内容的提问来源于stack exchange,提问作者samsmuthu
相关产品推荐
相关产品推荐

