Solved

.net Mail

Posted on 2008-10-21
13
328 Views
Last Modified: 2012-05-05
I am sending html emails from a windows form application the email is a table which which has all style contenet inline, this works fine if the recipient is using outlook if I test send the email to a msn email account the image appears as a grey square, If I forward the email from outlook to a msn account the image appears as it should! The code looks like the following:

Dim htmlContent1 As String = "<table border=""1"" bordercolor=""#000000"" cellpadding=""5"" cellspacing=""0"" style=""color: #ffffff; font-family: Arial Bold; vertical-align: middle; width: 600px; text-align: left""><td bgcolor=""#000000"" colspan=""2""><MARQUEE bgcolor=#000000 loop=-1 scrollamount=2 width=100%>My Message!!!!</MARQUEE></td></tr><tr><td colspan=""2""><span style=""color: #000000;font-size: 10pt; font-family: Arial"">" & txthtml & "</span></td></tr><tr><td colspan=""2"">"
            Dim htmlContent2 As String = "<img src=cid:companylogo><BR/><A HREF='" & URLtxt & "'>Visit&copy Key</A>"
            Dim htmlContent3 As String = "</td></tr><tr><td style=""width: 100px""><span style=""color: #000000; font-family: Arial Bold; font-size: 10pt; vertical-align: top; text-align: left"">" & ColDetail & "</span></td><td style=""width: 100px""><span style=""color: #000000; font-family: Arial Bold; font-size: 10pt; vertical-align: top; text-align: left"">" & DelDetail & " </span></td></tr><tr><td bgcolor=""#000000"" colspan=""2""><span style=""color: #ffffff; font-family: Arial"">Message sent " & Now() & "</span></td></tr></table>"

            Dim htmlView As System.Net.Mail.AlternateView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(htmlContent0 + htmlContent1 + htmlContent2 + htmlContent3, Nothing, "text/html")

            Dim logo As New LinkedResource("C:\images\EmailBanner.gif")
            logo.ContentId = "companylogo"

            htmlView.LinkedResources.Add(logo)

            'Me.WebBrowser1.Url = htmlView

            mail.AlternateViews.Add(htmlView)

            Dim smtp As New System.Net.Mail.SmtpClient("0.0.0.0")

Anyone tell me how to overcome this issue?

Regards,
JoeBo747
0
Comment
Question by:JoeBo747
  • 6
  • 4
  • 3
13 Comments
 
LVL 7

Expert Comment

by:talker2004
ID: 22768097
Is it possible to host the image as opposed to embedding it.

Also make sure that you have your hotmail account set to display images.

0
 
LVL 10

Expert Comment

by:jinn_hnnl
ID: 22768188
Make sure all of your html has to be in correct format, for example brreak line should be
<br /> instead of <br/>

you can just have to put single quote instead of double quote like that
<table border='1' bordercolor='#000000'

a lot of these atrributes won't  be supported by email client so make sure you stick to the most comment one and email supportive

Try to redo it first

JINN

cssForEmail3--CSS-property-.JPG
0
 
LVL 7

Expert Comment

by:talker2004
ID: 22768517
I would create an external html file and edit it through the ide or an html editor. At that point read the file in as a string. This is the easiest way to merge an html email doc.
0
 
LVL 7

Expert Comment

by:talker2004
ID: 22768563
Here is some code snippets from a sample program i developed. Reading the html file into your string is more flexible because you can run html validation on your html markup.


 Public Function MergeEmail(ByVal emailIdentifier As String) As String
        Dim FeedBackURL As String
        FeedBackURL = _
        System.Configuration.ConfigurationManager.AppSettings("FeedBackEmailURL").ToString()

        Dim strEmailContent As String = ""

        Try
            Dim objIO As New IOLib
            Dim FileBytes As Byte() = objIO.RetrieveServerFileBytes(FeedBackURL, "", "", "")
            If Not IsNothing(FileBytes) Then
                strEmailContent = objIO.ConvertBytesToString(FileBytes)
                strEmailContent = strEmailContent.Substring(3)
            End If
            objIO = Nothing
 
            strEmailContent = strEmailContent.Replace("#ContactFName#", txtFName.Value)
            strEmailContent = strEmailContent.Replace("#ContactLName#", txtLName.Value)
            strEmailContent = strEmailContent.Replace("#ContactEmail#", txtEmail.Value)
            strEmailContent = strEmailContent.Replace("#ContactMessage#", txtFeedBack.Value)
            strEmailContent = strEmailContent.Replace("#EmailIdentifier#", emailIdentifier)
        Catch ex As Exception

        End Try
 
        Return strEmailContent
 
    End Function
Imports Microsoft.VisualBasic

Imports System.Net

Imports System.IO
 

Public Class IOLib
 
 

    Public Function RetrieveServerFileBytes(ByVal SourceURL As String, Optional ByVal UserName As String = "", Optional ByVal Password As String = "", Optional ByVal Domain As String = "") As Byte()
 

        Try
 

            Dim wr As HttpWebRequest = _

            CType(WebRequest.Create(SourceURL), HttpWebRequest)
 

            Dim cr As New System.Net.NetworkCredential

            cr.UserName = UserName

            cr.Password = Password

            cr.Domain = Domain

            wr.Credentials = cr
 

            Dim ws As HttpWebResponse = CType(wr.GetResponse(), HttpWebResponse)

            Dim str As Stream = ws.GetResponseStream()

            Dim inBuf(100000) As Byte

            Dim bytesToRead As Integer = CInt(inBuf.Length)

            Dim bytesRead As Integer = 0

            While bytesToRead > 0

                Dim n As Integer = str.Read(inBuf, bytesRead, bytesToRead)

                If n = 0 Then

                    Exit While

                End If

                bytesRead += n

                bytesToRead -= n

            End While

            Return inBuf
 

        Catch ex As Exception
 

            Return Nothing

        End Try

    End Function
 

    Public Function ConvertBytesToString(ByVal BytesToConvert As Byte()) As String

        Try

            Dim dBytes As Byte() = BytesToConvert

            Dim str As String

            Dim enc As New System.Text.ASCIIEncoding()

            str = enc.GetString(dBytes)

            Return str

        Catch ex As Exception

            Return ""

        End Try

    End Function
 

End Class

Open in new window

0
 
LVL 1

Author Comment

by:JoeBo747
ID: 22769366
Hi ,
Thanks for both of your replies, there is quite a bit here to take on please bear with me, talker2004 your sample code uses: System.Configuration.ConfigurationManager.AppSettings("FeedBackEmailURL").ToString()
I get an error: ConfigurationManager is not a member of Configuration was the code written for an asp page? To run this code do I save the email with place holders as in your code #ContactFName# as a html file and then call MergeEmail(ByVal emailIdentifier As String) and pass the file name and path into the  into the variable emailIdentifier ?
Regards,
JoeBo747
0
 
LVL 7

Expert Comment

by:talker2004
ID: 22769446
I am on my blackberry right now at lunch when I get back I will try to give a better answer. You can add a reference to configuration manager and add the seitting to your config file. Or simply replace that line with a hard coded path to the html file.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 7

Accepted Solution

by:
talker2004 earned 300 total points
ID: 22769880
JoeBo, the email identifier was a custom job, it actually merged a unique identifier into a querystring which was part of an image tag. When the user opened the email my server was able to log in a database taht the user opened the email.

I will rework the routine below for you to better suit your purpose.

Now with this modification you can pass through

"http://mydomain.com/myemailmergebasefile.html"

I was pulling it from the configuration file.
Public Function MergeEmail(ByVal FeedbackURL As String) As String

         

        Dim strEmailContent As String = ""
 

        Try

            Dim objIO As New IOLib

            Dim FileBytes As Byte() = objIO.RetrieveServerFileBytes(FeedBackURL, "", "", "")

            If Not IsNothing(FileBytes) Then

                strEmailContent = objIO.ConvertBytesToString(FileBytes)

                strEmailContent = strEmailContent.Substring(3)

            End If

            objIO = Nothing

 

            strEmailContent = strEmailContent.Replace("#ContactFName#", txtFName.Value)

            strEmailContent = strEmailContent.Replace("#ContactLName#", txtLName.Value)

            strEmailContent = strEmailContent.Replace("#ContactEmail#", txtEmail.Value)

            strEmailContent = strEmailContent.Replace("#ContactMessage#", txtFeedBack.Value)

            strEmailContent = strEmailContent.Replace("#EmailIdentifier#", emailIdentifier)

        Catch ex As Exception
 

        End Try

 

        Return strEmailContent

 

    End Function

Open in new window

0
 
LVL 7

Expert Comment

by:talker2004
ID: 22769917


So in the html file you might have,


Hello, #ContactFName# how are you today.

<img src="http://mydomainname.com/myimagefile.jpg alt="my image"/>

Obviously the code i posted above will read in the merged html document which will be sent to the user.
0
 
LVL 1

Author Comment

by:JoeBo747
ID: 22775573
Hi talker2004,

Thank you for sharing your code, I have followed your suggestions and have a html file which looks like the code snippet below. I am able to replace the place holders with the content in every instance apart from the image which in the html editor is visible as an image. Can you spot my mistake?

regards,
JoeBo747

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
 

<head>

<meta http-equiv="Content-Language" content="en-us" />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>HTMLBase</title>

<style type="text/css">

.style2 {

	border-style:none;

	background-color:white;

	vertical-align: top;

	text-align: left;

	width: 50%;

	padding: 5;

}

.style3 {

	border-collapse: collapse;

	background-color:white;

	padding: 0;

}
 

.style4 {

	border-collapse: collapse;

	background-color: black;

	color: #FFFFFF;

}
 

</style>

</head>
 

<body>
 

<table style="width: 600px; height: 500px">

	<tr>

		<td colspan="2" class="style4"><strong>#marquee#</strong></td>

	</tr>

	<tr>

		<td style="height: 249px" colspan="2" class="style2"><strong>#salutation#</strong><br />

		<br />

		#body#</td>

	</tr>

	<tr>

		<td colspan="2" class="style3" style="height: 38px">

		<img src="http://localhost/webmail/EmailBanner.gif" alt="Banner" /><br />

<center >#href#</center></td>

	</tr>

	<tr>

		<td class="style2" style="height: 106px"><strong>Collection:<br />

		</strong>#collect#</td>

		<td class="style2" style="height: 106px"><strong>Delivery:</strong><br />

		#deliver#</td>

	</tr>

	<tr>

		<td colspan="2" class="style4">#timestamp#</td>

	</tr>

</table>
 

</body>
 

</html>

Open in new window

0
 
LVL 10

Assisted Solution

by:jinn_hnnl
jinn_hnnl earned 200 total points
ID: 22775634
You can implement the same idea, but you have to use inline css (instead of class="style4" you will have to set style specificly.

Mail client like Gmail or some another doesn't accept predefined css but inline css
so you might have to go:

<td colspan="2" style="background-color: black; color: #FFFFFF;"> <-this should work for most email client ... very supportive like Yahoo, hotmail ... to very basic like Gmail.

In my 1st post I have a list of CSS reference which refer to CSS support of each mail client. Check that and you might know why some css doesn't work

JINN

0
 
LVL 1

Author Comment

by:JoeBo747
ID: 22777662
Hi,

Thanks for the reply, I will check this out and get back.
Regards,
JoeBo
0
 
LVL 1

Author Closing Comment

by:JoeBo747
ID: 31508312
Hi,
That appears to be the answer, I would like to thank you both for your support hopefully you will agree to a share of the points based on the replies.
Thanks again,
JoeBo
0
 
LVL 10

Expert Comment

by:jinn_hnnl
ID: 22794052
Glad you worked it out. I have no problem with your shared given marks.

^^

Glad to help

JINN
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now