skip to Main Content

I wrote some code that sends emails and inserts a table cell from 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("[email protected]")

                    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", "[email protected]")

                    ' ----- 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

That code worked, and the email was successfully sent.
After that, I have added an image button to the last column in the Gridview:

enter image description here

Then emails stop being sent. Please suggest the above code for sending emails with or without the last column of image buttons.

tried nothing works

'To Export all pages.

GridView1.AllowPaging = False
Me.BindData_GridView1()

GridView1.HeaderRow.BackColor = Color.White
For Each cell As TableCell In GridView1.HeaderRow.Cells
    cell.BackColor = GridView1.HeaderStyle.BackColor
Next
For Each row As GridViewRow In GridView1.Rows
    row.BackColor = Color.White
    For Each cell As TableCell In row.Cells
        If row.RowIndex Mod 2 = 0 Then
            cell.BackColor = GridView1.AlternatingRowStyle.BackColor
        Else
            cell.BackColor = GridView1.RowStyle.BackColor
        End If
        cell.CssClass = "textmode"
    Next
Next

2

Answers


  1. Chosen as BEST ANSWER

    I got the solution from another forum, so I posted it below.

    HTML

    <%@ Page Title="" Language="vb" AutoEventWireup="false"  EnableEventValidation="false" MasterPageFile="~/abc/xyz.Master" CodeBehind="aaaa1.aspx.vb" Inherits="aaaa.sss" %>
    

    VB.NET

    Protected Sub SendRequestMail()
    Dim tryCount As Integer = 5
    Dim failed As Boolean = False
    Do
        Try
            failed = False
            Dim ToMailIDs As String
            ToMailIDs = LblRecipients.Text
            GridView1.Columns(GridView1.Columns.Count - 1).Visible = False
            Using sw As New StringWriter()
                Using hw As New HtmlTextWriter(sw)
                    GridView1.RenderControl(hw)
                    Dim sr As New StringReader(sw.ToString())
                    Dim smtpSection As Net.Configuration.SmtpSection = CType(ConfigurationManager.GetSection("system.net/mailSettings/smtp"), SmtpSection)
                    Dim mm As System.Web.Mail.MailMessage = New System.Web.Mail.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("[email protected]")
                    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", "[email protected]")
                    ' ----- 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
            GridView1.Columns(GridView1.Columns.Count - 1).Visible = True
        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

    Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control) End Sub
    

    Thank you


  2. Are the images provided by a URL?

    You could consider converting the image to a in-line "base64" string, and thus the html rendering for the GV would not include links.

    It is possible (but not yet determined) that you don’t want images as "links" to a url that is of course pointing to your site.

    In other words, if you attempting to add/render/inject/have/use/enjoy some images in the the html for that body, try using "strings" and not an actual URL to the image.

    So, say this example simple gv

    <h3>Hotels</h3>
    <asp:GridView ID="GridView1" runat="server" Width="40%"
        AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table table-striped">
        <Columns>
            <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
            <asp:BoundField DataField="LastName" HeaderText="LastName" />
            <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
            <asp:BoundField DataField="City" HeaderText="City" />
            <asp:BoundField DataField="Description" HeaderText="Description" />
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:ImageButton ID="cmdApprove" runat="server"
                        ImageUrl="~/Content/Pictures/check1.jpg"
                        Width="48"
                        OnClick="cmdApprove_Click" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    

    Code to load is this:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        If Not IsPostBack Then
            LoadGrid()
        End If
    
    End Sub
    
    Sub LoadGrid()
    
        GridView1.DataSource = Myrst("SELECT * FROM tblHotelsA ORDER BY Hotelname")
        GridView1.DataBind()
    
    End Sub
    

    And we now have this:

    enter image description here

    but, now lets hit f12 for browser dev tools, and elements, and inspect that ImageButton, and we find/get this:

    <input type="image" name="GridView1$ctl03$cmdApprove"
     id="GridView1_cmdApprove_1"
     src="../Content/Pictures/check1.jpg" 
     style="width:48px;">
    

    Well, I can’t see HOW that grid view going to THEN render in a email body, since you have path names and "urls" to your web site, and worse yet, they are relative path names that will ONLY work to the current given web site, and ONLY work on the CURRENT folder page

    Note the "../" for the path name! If you moved that web page to a different folder, NOT EVEN that simple path name would work anymore!!!

    So, lets remove the URL from that ImageButton.

    And lets "stream" + inject the picture as a imbedded byte array.

    So, our image button now becomes this:

    <ItemTemplate>
      <asp:ImageButton ID="cmdApprove" runat="server"
        Width="48"
        OnClick="cmdApprove_Click" />
    </ItemTemplate>
    

    So, no image.

    but, now, in the row data bound event, we do this:

    Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
    
    
        If e.Row.RowType = DataControlRowType.DataRow Then
    
            Dim ImageBtn As ImageButton = e.Row.FindControl("cmdApprove")
    
            ImageBtn.ImageUrl = gImageBytes("~/Content/Pictures/check1.jpg")
    
        End If
    
    End Sub
    
    
    Function gImageBytes(sFile As String) As String
    
        Dim sFileInternal As String =
            Server.MapPath(sFile)
    
    
        Dim iBytes As Byte() = File.ReadAllBytes(sFileInternal)
        Dim sMineType As String = MimeMapping.GetMimeMapping(sFileInternal)
    
        Return $"data:{sMineType};base64,{Convert.ToBase64String(iBytes, 0, iBytes.Length)}"
    
    
    End Function
    

    When we run, the gv looks the same.

    but, now inspecting the markup, we get/see this:

     <input type="image" name="GridView1$ctl02$cmdApprove"
     id="GridView1_cmdApprove_0" 
     src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAS etc." 
     style="width:48px;">
    

    I "cut" the rest of the bytes for the image, but note now, how the markup does NOT have a URL path name to some image on the web server – of which the client side email body will never have.

    So, the above would/could/will remove the path name to a image in that grid.

    However, even better?

    I would "hide" the buttons (visible = false) means that the html is NOT rendered in the gv, and thus you wind up removing the buttons 100%. So in row databound, hide the button(s) – their markup will NOT be rendered.

    So, say like this:

    At page class, define a flag, say like this:

    Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
    
    
        If e.Row.RowType = DataControlRowType.DataRow Then
    
            Dim ImageBtn As ImageButton = e.Row.FindControl("cmdApprove")
    
            ImageBtn.Visible = Not (bHideGridButtons)
    
            ImageBtn.ImageUrl = gImageBytes("~/Content/Pictures/check1.jpg")
    
        End If
    
    End Sub
    

    So, now gv becomes this:

    enter image description here

    Or, another idea? , and either create a 2nd gv, and use that for the email.

    (I can’t see the point to include the buttons in some email body anyway!).

    So, you could try removing the images.

    However, before one does ANY of that?

    Create a seperate 100% routine say like this:

    Call SendMailWeb(strTO, strSubject, 
          strBody, True, strCC, strBC, 
          FileAttachments, strReplyFromList)
    

    or "whatever".

    So, with a seperate routine to call, then this will allow easy coding, but ALSO allow you to make some test grids based on above ideas, such as removing the image link, and using "streaming"

    I VERY often for even display of images, or even for users to download a file?

    I don’t allow, proivde, use, have any public or file based "URL" path names allowed from the web site and markup. all file operations are 100% from code behind, and thus I never expose files at any time to allowable public URL’s from the web site. (this is done for security reasons, and also to say have users download a PDF document, but that folder of pdf’s is not exposed as any URL public path name.

    Code behind 100% ignores IIS security settings, and file path names are 100% plane jane server paths (good old fashioned windows path names). So, while this was a simple "image" example, it does show that URL’s to some images does NOT have to be a valid and existing URL for that image to display, but only code behind reading a file as bytes, and then steaming out the image as a base 64 image string.

    so, for darn near ANY image(s) in a email body, links and path names to pictures are NOT going to work in a email body on some client computer that may well not even have your web site URL’s to picture path names available at all.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search