
Introduction
This article presents a complete example of embedding an image in an email message. There are plenty of examples in the Internet; however, they are incomplete.
I spent many hours researching and getting the pieces together, and decided to share the results with my fellow developers.
Background
The code is based on functionality delivered by the .NET Framework (v 2.0, 3.0, and 3.5) which is not very efficient. If you plan to do some heavy emailing, please do not use this code.
The code is in VB, and the example is a one page website using VS 2008. You can copy and paste the code if you are using a previous version of VS.
Using the code
The code is very simple, and can be lifted and incorporated into an application easily. In fact, the basis of the code was used for a project for a client where the recipient's email address is selected from a GridView. (Can't post that one, is work-for-hire!)
Don't forget to update your web.config file! You can add the host and credentials inside the code, but I prefer to use the configuration file. Simply add the following lines to your web.config file:
<system.net>
<mailSettings>
<smtp from="user@somehost.com">
<network host="smtp.somehost.com" password="somepassword"
userName="user@somehost.com" port="587" />
</smtp>
</mailSettings>
</system.net>
The port should be 25, but some ISPs prefer that 587 is used. It makes no difference to the application.
Points of interest
With many of the other examples, you get an email with the graphic attached as a .dat file, not at all what is intended.
The missing ingredient is specifying the type of the attachment and its encoding:
Dim imageResourceEs As New _
System.Net.Mail.LinkedResource(fileImage.PostedFile.FileName, "image/gif")
imageResourceEs.TransferEncoding = Net.Mime.TransferEncoding.Base64
In most other examples, the second parameter is missing when creating the LinkedResource, and they fail to set an encoding for the file; thus it is attached instead of embedded.
Make sure to change the MIME type (image/GIF, image/JPEG, etc.) to match the type of the file you are embedding. The message body is a string formatted with HTML tags. Some renderers will let you do some things while other will balk, your mileage may vary.
The string is the parameter passed to CreateAlternateViewFromString, and as you can see in the example, I use a style to set the font family and size.
htmlView = System.Net.Mail.AlternateView.CreateAlternateViewFromString("<html><body " & _
"style='font-family:Segoe UI, Arial; font-size: 11pt;'><p>" & _
txtBody.Text.Trim & "</p>'<img src='cid:image1'></body></html>", Nothing, "text/html")
Basically, what we're doing is creating an "anchor" inside the HTML message with the code img src:'cid imageName' and then defining the resource and linking it so that the HTML renderer can find it.
Another important point is to make sure the name in the img tag in the HTML string is enclosed in quotes (single or double) and that it matches precisely the name of the resource:
img src="cid:image1"
imageResourceEs.ContentId = "image1"
Once you understand that we are using the img tag to allocate the "space" inside the HTML message and linking the resource so it can be found, you will see that adding multiple images is a matter of creating multiple tags and linking multiple resources:
!Inside the HTML message create the "holders" for the images
img src="cid:image1"
img src="cid:image2"
! Create the resources
Dim lkImage1 As New
System.Net.Mail.LinkedResource(FileName, "image/gif")
Dim lkImage2 As New
System.Net.Mail.LinkedResource(FileName, "image/gif")
! Link the resources
lkImage1.ContentId = "image1"
lkImage2.ContentId = "image2"
The message is displayed correctly in Gmail:

and Outlook:

I have tested the code with other email engines such as Yahoo! and others, but not Hotmail. It should work, but Hotmail is very quirky when rendering HTML messages.
The code also creates a "text view" incorporating the "body" of the message without the graphic element, so that something is displayed if the email client can't display the HTML version.
Enjoy!
History
- First version: December 19, 2008.
|
|
 |
 | email bounce Member 4545548 | 14:15 7 Jan '09 |
|
 |
Hi Jelizondo - thanks again - I am using your code and it works really well - I have just one question - when sending to certain email addresses I get a non delivery bounce back - I suspect this is to do with the security policy on the recipients exchange server
the error is : SMTP error from remote server after transfer of mail text + the ip of the remote + 550 5.7.1 Requested action not taken: message refused
do you know of a way of tweaking the app to get around this?
so far also I have tested your code also using iPhone and it works perfectly on that too, nice work!
Neil
|
|
|
|
 |
|
 |
Hello Neil:
Thanks for your note.
The problem is very undefined; it could be related to a any number of things from your mail server being blacklisted to the recipient having placed your email address in an internal blacklist or policy configuration error in the recipient's server.
Without a lot more information I'm unable to help you but I suggest that if your email is legitimate (i.e not unwanted spam) you set the reply-to field:
mailMessage.ReplyTo = New System.Net.Mail.MailAddress("yourname@yourcompany.com")
some servers use it to detect spam if the reply-to address can't be traced back or is empty.
If you are sending unwanted email then the problem complicates because it might be refused by any spam-detecting utility on the recipient's server and bypassing those is beyond my knowledge.
Cheers,
Jerry
|
|
|
|
 |
|
 |
Hello Neil,
I saw your post regarding this article Embed an Image in Email using ASP.NET. You have mentioned that you are using this option for iPhone also. I am very interested in knowing the way you are using this with iPhone mail client. I would love to have my iPhone application a feature of sending an embedded images. I have tried various options of doing this from my application, but could not succeed.
Through my iPhone application I would like to allow the users to send the current screen image as email within the body of the email. Currently I am allowing them to save and then they quit the application and from send an email from photo library.
Let me know if you can help me.
Regards, Saurabh
|
|
|
|
 |
 | thanks for sharing Member 4545548 | 13:47 7 Jan '09 |
|
 |
Hi, just wanted to say thanks for sharing!
|
|
|
|
 |
|
 |
Thank you for taking the time to drop a note. It really makes a difference and encourages one to continue to share the little knowledge one has.
|
|
|
|
 |
 | You realy doing great work Rai Shahid | 22:23 24 Dec '08 |
|
 |
Dear sir; I like ur work its very fine. I ask u to write more ur ideas coz people need such ideas but unable to find. Thanks for ur good article
Regards
R@! Shahid http://www.softbeats.net http://blogs.softbeats.net
|
|
|
|
 |
|
 |
Thank you for your kind words; I'm searching for other things that might be useful to write about.
|
|
|
|
 |
 | Very nice article 5 from me. Anurag Gandhi | 7:19 24 Dec '08 |
|
 |
Its a very nice article. This is the one i was searching for. Thanks a lot.
|
|
|
|
 |
|
 |
Thank you for your kind comments Anurag.
|
|
|
|
 |
 | nice article but 1 question Kishan Hathiwala | 6:26 24 Dec '08 |
|
 |
It was really nice article. But how can i embed more than 1 image in the same mail? Had search on net but couldnt find any. If you can help, that would be helpful.
Thanks & Regards, Kishan Hathiwala
No body is Perfect. And I am nobody.
|
|
|
|
 |
|
 |
Hello Kishan:
The first thing you need to do is create two (or more) "placeholders" in the HTML message, for example <img src='cid:imageEn'> and <img src='cid:image1'> in the code below:
htmlView = System.Net.Mail.AlternateView.CreateAlternateViewFromString("<html><body style='font-family: Segoe UI, Arial; font-size: 11pt;'<img src='cid:imageEn'><img src='cid:image1'></body></html>", Nothing, "text/html")
If you need more than two, simply add another <img src='cid:IMAGENAME'> placeholders. In my example I placed them together but they don't need to be consecutive.
Then you need to define and link the images. First we do ImageEn:
Dim imageResourceEn As New System.Net.Mail.LinkedResource(Server.MapPath("~") & "\images\\English.gif", "image/gif") imageResourceEn.ContentId = "imageEn" '<--- CORRRESPONDS to <img src='cid:ImageEn´> above imageResourceEn.TransferEncoding = Net.Mime.TransferEncoding.Base64 htmlView.LinkedResources.Add(imageResourceEn)
In the first line you create the resource from an image on disk. (Note that I use Server.MapPath to make the path relative to the website itself and the path needs double backslashes \\ to separate directories in the path.)
In the second line you give it the SAME name as used in the HTML message placeholder. In the third line you set the encoding and finally you link the resource.
The second image is then created in the same manner:
Dim imageResource As New System.Net.Mail.LinkedResource(Server.MapPath("~") & "\images\\XMAS 08-09.jpg", "image/jpeg") imageResource.ContentId = "image1" '<--- CORRRESPONDS to <img src='cid:image1´> above imageResource.TransferEncoding = Net.Mime.TransferEncoding.Base64 htmlView.LinkedResources.Add(imageResource)
Notice that in this instance I used a JPEG image and thus I need to set the MIME type to image/jpeg in the first line.
You can add more images in the same manner.
Cheers
|
|
|
|
 |
|
|
Last Updated 21 Dec 2008 |
Advertise |
Privacy |
Terms of Use |
Copyright ©
CodeProject, 1999-2010