Solved

.net Mail

Posted on 2008-10-21
13
334 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

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

[Webinar] Code, Load, and Grow

Managing multiple websites, servers, applications, and security on a daily basis? Join us for a webinar on May 25th to learn how to simplify administration and management of virtual hosts for IT admins, create a secure environment, and deploy code more effectively and frequently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

738 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