 |
|
 |
this is a really helpful codings that you have hope you can also teach me ^_^
|
|
|
|
 |
|
 |
When I run my Project with your code it tells RUNTIME Exception : Operation TimeOut
Please Suggest
|
|
|
|
 |
|
 |
Nice, excellent answer for my current problem
|
|
|
|
 |
|
 |
...cannot display content of this HTML message. If any of You people have solution for this problem, please send it....
|
|
|
|
 |
|
 |
How to implement HTML email template instead of HTML page?
The point is using People's names from database and parsing it into HTML template and use this class for newsletter. Please, some idea?
|
|
|
|
 |
|
 |
The code of this article using SYSTEM.NET.MAIL works fine for Outlook Express and Window Mail whereas Gmail and Yahoo Mail receive nothing.
I wish to switch to SYSTEM.WEB.MAIL to solve the problem, but I don't know how to use ALTERNATEVIEWS with SYSTEM.WEB.MAIL (I got error when trying set MAILMESSAGE.ALTERNATEVIEWS).
Does anyone have any suggestions?
Thanks
ZU
l-luong@sbcglobal.net
|
|
|
|
 |
|
 |
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!
|
|
|
|
 |
|
 |
Thanks for your great work but ineed your help because when i try to send Arabic page the letters appears as ??????
|
|
|
|
 |
|
 |
Fix:
byte[] bytes = System.Text.Encoding.Default.GetBytes(modifiedbody);
|
|
|
|
 |
|
 |
// 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);
|
|
|
|
 |
|
 |
Thanks Your code,
It help me a lot.
|
|
|
|
 |
|
 |
thanks a lot man.
|
|
|
|
 |
|
 |
Here is the modify version
How to use
// How to use ... Original Code 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);
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 url's
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't handle yet
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
///
///
///
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[] { '\"', ' ', '\'', '>' }, valueStartIndex);
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);
}
}
}
|
|
|
|
 |
|
 |
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
|
|
|
|
 |
|
|
 |
|
 |
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!!
|
|
|
|
 |
|
 |
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
|
|
|
|
 |
|
 |
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..
|
|
|
|
 |
|
 |
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.
|
|
|
|
 |
|
 |
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.
|
|
|
|
 |
|
|
 |
|
 |
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.
|
|
|
|
 |
|
 |
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...
///
///
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 url's
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't handle yet
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
///
///
///
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[] { '\"', ' ', '\'', '>' }, valueStartIndex);
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);
}
}
}
|
|
|
|
 |
|
 |
why dosent work this code.
error :
Using the generic type 'System.Collections.Generic.IComparer requires '1'
thanks.
|
|
|
|
 |
|
 |
Can you make a dll?
|
|
|
|
 |