 |
|
 |
Thanks for your good solution.
I have a problem. When I use css to control the url of background-image, the background-images didn't diaplay. I checked the modifedhtml, all the urls of the background-image were replaced correctly. And I can get these background-images in Attachment, but not in the email body. Do you have any idea on this?
Thans a lot!
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
Thanks for your great work but ineed your help because when i try to send Arabic page the letters appears as ??????
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
// Write the html to a memory stream MemoryStream stream = new MemoryStream(); //byte[] bytes = System.Text.Encoding.ASCII.GetBytes(modifiedbody); byte[] bytes = System.Text.Encoding.Default.GetBytes(modifiedbody);
// Pipes the stream to a higher level stream reader with the required encoding format. //StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); StreamReader readStream = new StreamReader(receiveStream, Encoding.Default);
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Here is the modify version
How to use
Uri uri = new Uri("http://about.com/");
Fmd.Mail.WebpageMailer mailer = new Fmd.Mail.WebpageMailer(); mailer.SmtpServerName = "mail.somesmptserver.com"; mailer.Delay = 0; mailer.MailMessage.From = new MailAddress("noreply@somedomain.com"); mailer.MailMessage.To.Add(new MailAddress("recipient@somedomain.com")); mailer.MailMessage.Subject = "Automatic Mail Message " + DateTime.Now.ToShortDateString() mailer.MailMessage.Priority = MailPriority.Normal; mailer.SmtpServerPassword = "somesmtppassword"; mailer.SmtpServerUserName = "somesmtpusername";
mailer.SendMailMessage(uri);
the modified code
using System; using System.Collections.Generic; using System.Text; using System.Net.Mail; using System.Net; using System.IO;
namespace Framework.Web { public class WebpageMailer { MailMessage _mailMessage = new MailMessage(); public MailMessage MailMessage { get { return _mailMessage; } }
string _smptServerName; public string SmtpServerName { get { return _smptServerName; } set { _smptServerName = value; } }
string _smptServerUserName; public string SmtpServerUserName { get { return _smptServerUserName; } set { _smptServerUserName = value; } }
string _smptServerPassword; public string SmtpServerPassword { get { return _smptServerPassword; } set { _smptServerPassword = value; } }
int _delay; /// /// The delay can be used to relieve stress from a webserver /// It is the number of milliseconds that the application waits before retrieving the next image /// public int Delay { get { return _delay; } set { _delay = value; } }
/// /// Sends the contents of the uri as a mailmessage /// The mail message should be configured first with recipient atc... /// /// public void SendMailMessage(Uri uri) { // Retrieve the contents string htmlbody = GetBody(uri);
// See what images there are to embed string modifiedbody; List<LinkedResource> foundResources; ExtractLinkedResources(uri, htmlbody, out modifiedbody, out foundResources);
// Write the html to a memory stream MemoryStream stream = new MemoryStream(); byte[] bytes = System.Text.Encoding.ASCII.GetBytes(modifiedbody); stream.Write(bytes, 0, bytes.Length); stream.Position = 0;
// Configure the mail so it contains the html page _mailMessage.Body = "This is a html mail - use an email client that can read it"; AlternateView altView = new AlternateView(stream, System.Net.Mime.MediaTypeNames.Text.Html);
// Embed the images into the mail foreach (LinkedResource linkedResource in foundResources) { altView.LinkedResources.Add(linkedResource); } _mailMessage.AlternateViews.Add(altView);
// Send the mail SmtpClient client = new SmtpClient(_smptServerName);
if (((_smptServerUserName != null) && (_smptServerPassword != null)) && ((_smptServerUserName.Length > 0) && (_smptServerPassword.Length > 0))) { NetworkCredential nc = new NetworkCredential(_smptServerUserName, _smptServerPassword); client.Credentials = nc; }
client.Send(_mailMessage); }
/// /// Gets the body of the mail message /// /// /// public static string GetBody(Uri uri) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// Set some reasonable limits on resources used by this request request.MaximumAutomaticRedirections = 4; request.MaximumResponseHeadersLength = 4; // Set credentials to use for this request. request.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Get the stream associated with the response. Stream receiveStream = response.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
string body = readStream.ReadToEnd(); readStream.Close();
response.Close(); return body; }
/// /// Retrieves an image to embed /// /// /// /// Stream GetImageStream(Uri uri, out string contentType) { System.Threading.Thread.Sleep(_delay);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// Set some reasonable limits on resources used by this request request.MaximumAutomaticRedirections = 4; request.MaximumResponseHeadersLength = 4; // Set credentials to use for this request. request.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Get the stream associated with the response. Stream receiveStream = response.GetResponseStream();
BinaryReader binaryReader = new BinaryReader(receiveStream); MemoryStream memoryStream = new MemoryStream(); try { while (true) { byte b = binaryReader.ReadByte(); // Not so efficient but it works... memoryStream.WriteByte(b); } } catch (EndOfStreamException) { memoryStream.Position = 0; }
contentType = response.ContentType; response.Close(); return memoryStream; }
private void ExtractLinkedResources(Uri uri, string html, out string modifiedhtml, out List<LinkedResource> linkedResources) { modifiedhtml = html; linkedResources = new List<LinkedResource>();
List imageNames = ExtractImageNames(html);
int imageID = 1;
foreach (string imageName in imageNames) { try { // Deal with some escape characters that can occur in dynamic image urlstring workaroundImageName = imageName.Replace("&", "&");
// Generate the uri to retrieve the image - usually an image path is relative to the page uri Uri imageUri = new Uri(uri, workaroundImageName);
// Retrieve the image string contentType; Stream imageStream = GetImageStream(imageUri, out contentType);
// Fill the linked resource LinkedResource data = new LinkedResource(imageStream);
// Determine a name and set the media type of the linked resource string generatedName = null; if (contentType.ToLower().IndexOf("image/gif") >= 0) { data.ContentType.MediaType = System.Net.Mime.MediaTypeNames.Image.Gif; generatedName = "image" + imageID.ToString() + ".gif"; } else if (contentType.ToLower().IndexOf("image/jpeg") >= 0) { data.ContentType.MediaType = System.Net.Mime.MediaTypeNames.Image.Jpeg; generatedName = "image" + imageID.ToString() + ".jpeg"; }
// it is something that I donif (generatedName == null) continue;
// Generate the linked resource for the image being embedded string generatedSrc = "cid:" + generatedName; data.ContentType.Name = generatedName; data.ContentId = generatedName; data.ContentLink = new Uri(generatedSrc); linkedResources.Add(data);
// Let the html refer to the linked resource modifiedhtml = modifiedhtml.Replace(imageName, generatedSrc); } catch { modifiedhtml = modifiedhtml.Replace(imageName, "#"); }
imageID++; } }
/// /// longest length first /// private class LengthComparer : IComparer { public int Compare(string x, string y) { return -x.Length.CompareTo(y.Length); } }
/// /// Sorts the list of strings so the longest names are in the start of the list /// When there is an image named "a.aspx?id=1" and another named "a.aspx?id=12", the list should start with "a.aspx?id=12" /// This guarantees that string replacement will not damage the names /// /// /// static private List SortNoDuplicate(List input) { List result = new List(input); IComparer comparer = new LengthComparer(); result.Sort(comparer); return result; }
/// /// Optimistic search for image names in an html document /// The images found here will be embedded into the email /// /// /// private static List ExtractImageNames(string html) { List imagenames = new List(); string[] imageattributes = new string[] { "src=", "background=" }; foreach (string imageattribute in imageattributes) { int position = 0; while (position < html.Length) { int foundIndex = html.ToLower().IndexOf(imageattribute, position); if (foundIndex < 0) { position = html.Length; } else { int valueStartIndex = foundIndex + imageattribute.Length + 1; int foundIndexEnd = html.IndexOfAny(new char[] { if (foundIndexEnd < 0) { position = html.Length; } else { string relativeimagename = html.Substring(valueStartIndex, foundIndexEnd - valueStartIndex); relativeimagename = relativeimagename.Trim(new char[] { if (!imagenames.Contains(relativeimagename)) { imagenames.Add(relativeimagename); } position = foundIndexEnd; } } } } return SortNoDuplicate(imagenames); } } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
If you want to use the file:// protocol you just need to do this changes in WebpageMailer.cs:
In SendMailMessage():
if (uri.IsFile) htmlbody = File.ReadAllText(uri.LocalPath); else htmlbody = GetBody(uri);
Inside the loop in ExtractLinkedResources():
// Retrieve the image string contentType = "image/gif"; Stream imageStream;
if (imageUri.IsFile) imageStream = new StreamReader(imageUri.LocalPath).BaseStream; else imageStream = GetImageStream(imageUri, out contentType);
----
I have used this in a scenario that the Mailer, runs on a server that has restricted access to the Internet and need to get the resources locally. This is the sample:
// Setup resource path. Uri uri = new Uri(@"file://d:\Websites\LocalUser\regrazero.com\200701a\index.htm");
// Configure E-mail message.
Fmd.Mail.WebpageMailer mailer = new Fmd.Mail.WebpageMailer(); mailer.SmtpServerName = "mail.regrazero.com"; mailer.Delay = 0; mailer.MailMessage.From = new MailAddress("contato@regrazero.com"); mailer.MailMessage.To.Add(new MailAddress("rodriguez@regrazero.com")); mailer.MailMessage.Subject = "Regra Zero Notícias (Julho 2007)"; mailer.MailMessage.Priority = MailPriority.Normal;
// Sends the webpage using a local resource.
mailer.SendMailMessage(uri);
Rodrigo Rodriguez
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
Does this work with HTML; like the following
This is a test1
This is a test2
<img src="file.aspx?id=photo.jpg"> This is a test3
<img src="file.aspx?id=train.jpg"> This is a test3
This is a test3
File.aspx?id= - brings back the image from a SQL table
Thanks
Nice code!!
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
 |
I am asp.net developer i download code from your article and open this file in asp.net 1.1 but it show errors.i want to ask you whether this code for asp.net 1.1 or asp.net 2.0 .please tell me how can i use this code. Thanks
tariq
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Since this article relies on the LinkedResource class which is new in .Net Framework 2.0, it cannot be used in .Net 1.1 unfortunately..
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanks for your solustion of sending the embended email.
Now i have some question to send a email. I want to write a email(which have some pictures) as a templete, then save the email contents to the database. I want to review the email contents and change something later.
Can you help me?
Thanks lots.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
What you want to do is similar to what I wrote, in the sense that the same control flow can be used. You will have to make a few modifications to suit it to your needs.
In step 1 where I get the html code from a webserver, you will have to read your template from a file or database.
In step 3 where I get the images from a webserver, you will have to read the images from your file system or a database.
Before you send the email you will have to get the (changed) email contents from the database and insert it into the template.
I am not sure how you are planning to use the database. Will it have to contain the entire email, or just the contents (text)? Will the database contain the images, or will the images and the template be on your file system? How do you want to review the contents? If you provide some more details about your planned usage, I may be able to give more specific tips or pointers.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
In my article I rely on the services provided in the namespace System.Net.Mail, and combine these to perform a task. That means that to authenticate to an smpt server, you would have to use the authentication services provided by the classes in System.Net.Mail.
I think that you need to make a small change in the place where the mail is actually sent. System.Net.Mail.SmtpClient has a property Credentials that I do not use. I think that you need to provide the credentials there. You can see an example of setting credentials on system.net.mail.smtpclient.credentials[^]
I hope this helps.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
i already edit this code just to support smtp connection. see my code implementation below
using System; using System.Collections.Generic; using System.Text; using System.Net.Mail; using System.Net; using System.IO;
namespace Framework.Web {
// How to use ... Reference URL : http://www.codeproject.com/cs/internet/Mail_Webpage_with_images.asp //// The contents that will be sent //Uri uri = new Uri("http://about.com/");
//// Configuration of the email message //Fmd.Mail.WebpageMailer mailer = new Fmd.Mail.WebpageMailer(); //mailer.SmtpServerName = "mail.somesmptserver.com"; //mailer.Delay = 0; //mailer.MailMessage.From = new MailAddress("noreply@somedomain.com"); //mailer.MailMessage.To.Add(new MailAddress("recipient@somedomain.com")); //mailer.MailMessage.Subject = "Automatic Mail Message " + // DateTime.Now.ToShortDateString(); //mailer.MailMessage.Priority = MailPriority.Normal; //mailer.SmtpServerPassword = "somesmtppassword"; //mailer.SmtpServerUserName = "somesmtpusername";
//// Sending the webpage //mailer.SendMailMessage(uri);
public class WebpageMailer { MailMessage _mailMessage = new MailMessage(); public MailMessage MailMessage { get { return _mailMessage; } }
string _smptServerName; public string SmtpServerName { get { return _smptServerName; } set { _smptServerName = value; } }
string _smptServerUserName; public string SmtpServerUserName { get { return _smptServerUserName; } set { _smptServerUserName = value; } }
string _smptServerPassword; public string SmtpServerPassword { get { return _smptServerPassword; } set { _smptServerPassword = value; } }
int _delay; /// /// The delay can be used to relieve stress from a webserver /// It is the number of milliseconds that the application waits before retrieving the next image /// public int Delay { get { return _delay; } set { _delay = value; } }
/// /// Sends the contents of the uri as a mailmessage /// The mail message should be configured first with recipient atc... /// /// "uri"> public void SendMailMessage(Uri uri) { // Retrieve the contents string htmlbody = GetBody(uri);
// See what images there are to embed string modifiedbody; List<LinkedResource> foundResources; ExtractLinkedResources(uri, htmlbody, out modifiedbody, out foundResources);
// Write the html to a memory stream MemoryStream stream = new MemoryStream(); byte[] bytes = System.Text.Encoding.ASCII.GetBytes(modifiedbody); stream.Write(bytes, 0, bytes.Length); stream.Position = 0;
// Configure the mail so it contains the html page _mailMessage.Body = "This is a html mail - use an email client that can read it"; AlternateView altView = new AlternateView(stream, System.Net.Mime.MediaTypeNames.Text.Html);
// Embed the images into the mail foreach (LinkedResource linkedResource in foundResources) { altView.LinkedResources.Add(linkedResource); } _mailMessage.AlternateViews.Add(altView);
// Send the mail SmtpClient client = new SmtpClient(_smptServerName); if (((_smptServerUserName != null) && (_smptServerPassword != null)) && ((_smptServerUserName.Length > 0) && (_smptServerPassword.Length > 0))) { NetworkCredential nc = new NetworkCredential(_smptServerUserName, _smptServerPassword); client.Credentials = nc; }
client.Send(_mailMessage); }
/// /// Gets the body of the mail message /// /// "uri"> /// public static string GetBody(Uri uri) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// Set some reasonable limits on resources used by this request request.MaximumAutomaticRedirections = 4; request.MaximumResponseHeadersLength = 4; // Set credentials to use for this request. request.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Get the stream associated with the response. Stream receiveStream = response.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
string body = readStream.ReadToEnd(); readStream.Close();
response.Close(); return body; }
/// /// Retrieves an image to embed /// /// "uri"> /// "contentType"> /// Stream GetImageStream(Uri uri, out string contentType) { System.Threading.Thread.Sleep(_delay);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// Set some reasonable limits on resources used by this request request.MaximumAutomaticRedirections = 4; request.MaximumResponseHeadersLength = 4; // Set credentials to use for this request. request.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Get the stream associated with the response. Stream receiveStream = response.GetResponseStream();
BinaryReader binaryReader = new BinaryReader(receiveStream); MemoryStream memoryStream = new MemoryStream(); try { while (true) { byte b = binaryReader.ReadByte(); // Not so efficient but it works... memoryStream.WriteByte(b); } } catch (EndOfStreamException) { memoryStream.Position = 0; }
contentType = response.ContentType; response.Close(); return memoryStream; }
private void ExtractLinkedResources(Uri uri, string html, out string modifiedhtml, out List<LinkedResource> linkedResources) { modifiedhtml = html; linkedResources = new List<LinkedResource>();
List imageNames = ExtractImageNames(html);
int imageID = 1;
foreach (string imageName in imageNames) { try { // Deal with some escape characters that can occur in dynamic image url string workaroundImageName = imageName.Replace("&", "&");
// Generate the uri to retrieve the image - usually an image path is relative to the page uri Uri imageUri = new Uri(uri, workaroundImageName);
// Retrieve the image string contentType; Stream imageStream = GetImageStream(imageUri, out contentType);
// Fill the linked resource LinkedResource data = new LinkedResource(imageStream);
// Determine a name and set the media type of the linked resource string generatedName = null; if (contentType.ToLower().IndexOf("image/gif") >= 0) { data.ContentType.MediaType = System.Net.Mime.MediaTypeNames.Image.Gif; generatedName = "image" + imageID.ToString() + ".gif"; } else if (contentType.ToLower().IndexOf("image/jpeg") >= 0) { data.ContentType.MediaType = System.Net.Mime.MediaTypeNames.Image.Jpeg; generatedName = "image" + imageID.ToString() + ".jpeg"; }
// it is something that I don if (generatedName == null) continue;
// Generate the linked resource for the image being embedded string generatedSrc = "cid:" + generatedName; data.ContentType.Name = generatedName; data.ContentId = generatedName; data.ContentLink = new Uri(generatedSrc); linkedResources.Add(data);
// Let the html refer to the linked resource modifiedhtml = modifiedhtml.Replace(imageName, generatedSrc); } catch { modifiedhtml = modifiedhtml.Replace(imageName, "#"); }
imageID++; } }
/// /// longest length first /// private class LengthComparer : IComparer { public int Compare(string x, string y) { return -x.Length.CompareTo(y.Length); } }
/// /// Sorts the list of strings so the longest names are in the start of the list /// When there is an image named "a.aspx?id=1" and another named "a.aspx?id=12", the list should start with "a.aspx?id=12" /// This guarantees that string replacement will not damage the names /// /// "input"> /// static private List SortNoDuplicate(List input) { List result = new List(input); IComparer comparer = new LengthComparer(); result.Sort(comparer); return result; }
/// /// Optimistic search for image names in an html document /// The images found here will be embedded into the email /// /// "html"> /// private static List ExtractImageNames(string html) { List imagenames = new List(); string[] imageattributes = new string[] { "src=", "background=" }; foreach (string imageattribute in imageattributes) { int position = 0; while (position < html.Length) { int foundIndex = html.ToLower().IndexOf(imageattribute, position); if (foundIndex < 0) { position = html.Length; } else { int valueStartIndex = foundIndex + imageattribute.Length + 1; int foundIndexEnd = html.IndexOfAny(new char[] { if (foundIndexEnd < 0) { position = html.Length; } else { string relativeimagename = html.Substring(valueStartIndex, foundIndexEnd - valueStartIndex); relativeimagename = relativeimagename.Trim(new char[] { if (!imagenames.Contains(relativeimagename)) { imagenames.Add(relativeimagename); } position = foundIndexEnd; } } } } return SortNoDuplicate(imagenames); } } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
why dosent work this code. error : Using the generic type 'System.Collections.Generic.IComparer requires '1'
thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Creating a dll can be done like this:
1. In visual studio, go to File-New-Project and choose C# Class Library 2. Insert my sample file into the project (or copy the code into Class1) 3. Compile as release
and you have created a dll that you can use in your other projects.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I think that those content types you mention are difficult to do.
When you search on google you are going to find things like this: http://www.campaignmonitor.com/blog/archives/2006/01/the_truth_about_1.html[^] That suggests that you are about to expect trouble when you are going to try to send flash movies.
Since email clients try to protect their users from unwanted spam I expect the same trouble with anything that is too 'intrusive'.
MediaTypeNames.Image supports Gif, Jpef and Tiff, so I'm afraid that other types are not so easy to embed.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
If it is an asp.net app (i.e. the HttpContext is not null) then the easiest way to get the body is just doing a Server.Execute.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |