VS.NET 2010/2012 Users Click Here   

HOMECONTACT PRODUCTS DOWNLOADS PURCHASE TESTIMONIALS FORUMS COMPANY CONTACT
Home
Products
Downloads
Purchase
Licensing
Licensing FAQ
Software Updates
Support Forums
Testimonials
Feature Requests
Guarantee
About Us
Contact Us
Hosting Companies
Privacy Policy
   
Shopping Cart


Search

aspNetEmail supports Amazon SES

by Dave 31. March 2011 08:08

aspNetEmail now supports Amazon Simple Email Service (SES). This latest update is still in beta. If you would like a beta to test, feel free to contact us using the Contact Us page and request the aspNetEmail update.  Be sure to specify you want the beta version that supports Amazon SES.

When beta testing has been completed to satisfaction, the functionality will be rolled into the production release of aspNetEmail.

If anyone has any questions, feel free to contact me, again, using the Contact Us page.

Thank you,
Dave Wanta

aspNetMHT: Replacing images in the MHT document

by Dave 4. March 2011 10:45

I recently had an email request, asking if aspNetMHT could be used to switch out images.

In this particular instance, the customer wanted to convert a Url to a MHT document. However, the images were larger than desired. So, the requestor asked if aspNetMHT would allow images to be swapped out.

The following code example demonstrates this capability. In this example, we are going to examine the content-location value of each MHTPart. For simplicity sake, we are simply going to find all .png images, and swap them out with an image named "sample.png". In a production scenario, we would make some logic based decisions when swapping out the images.

Here is the code.


C#

static void Example()
{
	string url = "http://www.google.com";

	MHT m = new MHT();

	//enable logging for any troubleshooting
	m.Logger= new MHTLog("c:\\temp\\mht.log");
	m.Logger.Enabled =true;
	m.Logger.Overwrite=true;
	m.Ignore404=true;

	m.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";


	m.LoadUrl(url);
	m.Parse();

	ReplaceImages( m );

	m.SaveToFile("c:\\temp\\");

}


static void ReplaceImages(MHT m)
{
	MHTPartCollection parts = m.RetrieveAllParts();

	foreach( MHTPart part in parts )
	{
		if( part.ContentLocation != null )
		{
			string cl = part.ContentLocation.Value;
			if( cl != null )
			{
				cl = cl.ToLower();
				//as a simple test, replace all .png images
				if( cl.EndsWith(".png") )
				{
					//read in the replacement image
					FileStream fs = File.OpenRead("c:\\temp\\sample.png");
					byte[] data = new byte[ fs.Length ];
					fs.Read( data, 0, data.Length );
					fs.Close();
					part.Data = data;
				}
			}
		}
	}
}


VB.NET

Shared Sub Example()
   Dim url As String = "http://www.google.com"
   
   Dim m As New MHT()
   
   'enable logging for any troubleshooting
   m.Logger = New MHTLog("c:\temp\mht.log")
   m.Logger.Enabled = True
   m.Logger.Overwrite = True
   m.Ignore404 = True
   
   m.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"
   
   
   m.LoadUrl(url)
   m.Parse()
   
   ReplaceImages(m)
   
   m.SaveToFile("c:\temp\")
End Sub 'Example
 


Shared Sub ReplaceImages(m As MHT)
   Dim parts As MHTPartCollection = m.RetrieveAllParts()
   
   Dim part As MHTPart
   For Each part In  parts
      If Not (part.ContentLocation Is Nothing) Then
         Dim cl As String = part.ContentLocation.Value
         If Not (cl Is Nothing) Then
            cl = cl.ToLower()
            'as a simple test, replace all .png images
            If cl.EndsWith(".png") Then
               'read in the replacement image
               Dim fs As FileStream = File.OpenRead("c:\temp\sample.png")
               Dim data(fs.Length) As Byte
               fs.Read(data, 0, data.Length)
               fs.Close()
               part.Data = data
            End If
         End If
      End If
   Next part
End Sub 'ReplaceImages


As always, if anyone has any questions, let me know.

Thanks!
Dave Wanta

 

aspNetMHT: Converting the current ASP.NET page to a MHT Document

by Dave 3. March 2011 09:53

I received an email from Jeff W. the other day, and he had an interesting requirement.

He wanted to save the current contents of the ASP.NET page, to a MHT document.

This is a little different than the normal situation, because normally aspNetMHT is pointed at a Url, and the remote Url is downloaded, and converted to the MHT document.

In this particular scenario, Jeff wanted to save the contents of the ASP.NET page being rendered, from inside of the page. It turns out this is possible by accessing the Render event.  If you override the render with the code below, you can save the current contents, and convert them to a MHT documents.

As always, if anyone has any questions, feel free to contact me through the Contact Us page.


C#

protected override void Render(HtmlTextWriter writer) 
{ 
	System.IO.StringWriter sw = new System.IO.StringWriter(); 
	HtmlTextWriter localWriter = new HtmlTextWriter(sw); 
	base.Render(localWriter); 

	//get the contets of the page
	string html = sw.ToString(); 

    
	//check to see if the page was posted

	if( Page.IsPostBack )
	{
    
		//save it to a MHT file

		MHT m = new MHT();

		//this is the url of this page. It's used so aspNetMHT can resolve any images.
		string url = "http://localhost/mhttest/CaptureSubmission.aspx";
		m.LoadString( html, url );
		m.Parse();

		//save the MHT to the filesystem
		string path = "c:\\temp\\" + DateTime.Now.ToFileTime() + "_sample.mht";
		m.SaveToFile( path );
	}


	//continue sending the html to the browser
	writer.Write(html); 
}


VB.NET

Protected Overrides Sub Render(writer As HtmlTextWriter)
   Dim sw As New System.IO.StringWriter()
   Dim localWriter As New HtmlTextWriter(sw)
   MyBase.Render(localWriter)
   
   'get the contets of the page
   Dim html As String = sw.ToString()
   
   
   'check to see if the page was posted
   If Page.IsPostBack Then
      
      'save it to a MHT file
      Dim m As New MHT()
      
      'this is the url of this page. It's used so aspNetMHT can resolve any images.
      Dim url As String = "http://localhost/mhttest/CaptureSubmission.aspx"
      m.LoadString(html, url)
      m.Parse()
      
      'save the MHT to the filesystem
      Dim path As String = "c:\temp\" + DateTime.Now.ToFileTime() + "_sample.mht"
      m.SaveToFile(path)
   End If
   
   
   'continue sending the html to the browser
   writer.Write(html)
End Sub 'Render

 

 

BC30002: Type 'aspNetMHT.MHT' is not defined

by Dave 3. March 2011 06:58

I recently had a potential aspNetMHT customer email me with the following error.

BC30002: Type 'aspNetMHT.MHT' is not defined

Their entire code page looked like:

 
<%@ Page Language="vb" AutoEventWireup="true" %>
<script runat=server>
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim url As String = "http://www.google.com"
 
   'create a MHT object referencing google.com
    Dim m As New aspNetMHT.MHT(url)
 
    'parses the url into it's MHT parts
    m.Parse()
 
    'create a zipped MHT file of google.com
    Dim filename As String = "google.zip"
 
    'save it the filesystem. You will need write permissions to do this
    m.SaveToFile(Server.MapPath(filename), True)
 
    Response.Write(String.Format("Dowload the MHT file <a href='{0}'>here</a>", filename))
 
End Sub
</script>

For anyone else out there, the resolution is as follows:

a)Be sure you import/upload the aspNetMHT.dll into your /bin directory
b)Add the following commands at the top of the .aspx page
<%@ Assembly Name="aspNetMHT"%>
<%@ Import Namespace="aspNetMHT" %>

This will set a reference to the aspNetMHT.dll assembly
(notice the .dll extension is missing from the @Assembly directive), and it imports the aspNetMHT namespace.

Downloading email using aspNetIMAP from Gmail

by Dave 2. March 2011 02:51


aspNetIMAP can easily fetch email from Gmail. To do this you must do the following:

a) Configure IMAP access in Gmail
b) Download the AdvancedIntellect.Ssl.dll from www.advancedintellect.com/download.aspx
c) Use aspNetIMAP over SSL at port 993 to connect.

Lets discuss this below.

Configure IMAP access in Gmail

Before you can access email, you must first configure IMAP in Gmail. To do this, log into Gmail, and click on the settings tab. You should see something similar to what is below. Basically, you want select "Enable IMAP".


Download the AdvancedIntellect.Ssl.dll
Once you have IMAP configured in Gmail, you need to download the AdvancedIntellect,Ssl.dll plugin to use with aspNetIMAP. You can download the dll from:
http://www.advancedintellect.com/download.aspx
Gmail only allows you to connect over IMAP using SSL. The  AdvancedIntellect,Ssl.dll allows you to do this.

Use aspNetIMAP over SSL at port 993 to connect.
Once you've downloaded the dll, you can integrate it into your project.

If you are using VS.NET, import the dll into your application, and set a reference to it.

If you are not using VS.NET, you should be able to just copy the dll to your /bin directory.

Once that is done, the following code example will get you started. This example simply downloads the message count from your inbox, and loops through the headers of the individual messages.


C#

IMAP4 imap = new IMAP4( "imap.gmail.com" );

//create and load the ssl socket
AdvancedIntellect.Ssl.SslSocket ssl = new AdvancedIntellect.Ssl.SslSocket();
imap.LoadSslSocket( ssl );

//logging on the ssl socket
ssl.Logging = true;
ssl.LogPath = "c:\\ssl.log";


//rest of the IMAP properties
imap.Port = 993;
imap.Username = "MyAccount@gmail.com";
imap.Password = "MyPassword";

//any logging for troubleshooting
imap.Logger = new IMAPLog();
imap.Logger.Path = "c:\\imap.log";
imap.Logger.Overwrite = true;

imap.Connect();

imap.Login();


//get the message count
MailFolder inbox = imap.SelectInbox();
int count = inbox.MessageCount;

//write it out
Response.Write( count.ToString() );

FetchClient fc = inbox.FetchClient;
//get the headers for each message (IMAP is a '1' based index. Start at '1'
for( int i=1;i<=count;i++)
{
	string headers = fc.Headers(i, IndexType.Ordinal );

	//do some work on the headers
	DoWork( headers );
}

imap.Disconnect();


VB.NET

Dim imap As New IMAP4("imap.gmail.com")

'create and load the ssl socket
Dim ssl As New AdvancedIntellect.Ssl.SslSocket()
imap.LoadSslSocket(ssl)

'logging on the ssl socket
ssl.Logging = True
ssl.LogPath = "c:\ssl.log"


'rest of the IMAP properties
imap.Port = 993

'any logging for troubleshooting
imap.Logger = New IMAPLog()
imap.Logger.Path = "c:\imap.log"
imap.Logger.Overwrite = True

imap.Connect()


imap.Username = "MyAccount@gmail.com"
imap.Password = "MyPassword"
imap.Login()


'get the message count
Dim inbox As MailFolder = imap.SelectInbox()
Dim count As Integer = inbox.MessageCount

'write it out
Response.Write(count.ToString())

Dim fc As FetchClient = inbox.FetchClient
'get the headers for each message (IMAP is a '1' based index. Start at '1'
Dim i As Integer
For i = 1 To count
   Dim headers As String = fc.Headers(i, IndexType.Ordinal)
   
   'do some work on the headers
   DoWork(headers)
Next i

imap.Disconnect()


As always, if anyone has any questions, feel free to contact me over at the Contact Us web page.


Thanks,
Dave Wanta

iCalendar as an Email Body

by Dave 14. October 2010 01:58

 Recently I had a request about sending an iCalendar (Meeting Request) object, as the email body itself, rather than as an attachment.(Thanks Paras!)

Background
iCalendars are special attachments that can be used to represent Meeting Requests or Appointments. By default, most mail systems like to have the iCalendar  object as an alternative body. In fact, that is how I wrote aspNetEmail to work. When you can create and add an iCalendar to the EmailMessage object, under the covers, aspNetEmail actually adds it to the internal body parts collection.

Below are 3 code examples. One example demonstrates creating a standard iCalendar enabled  email.  The 2nd example demonstrates creating email that has the iCalendar as the body. The 3rd example offers a combination of the 2.

All 3 of these examples use the following helper method called CreateiCal(…)

Create iCal creates a very simple iCalendar object, that has a meeting set tomorrow at 10am.

public iCalendar CreateiCal()
{
	iCalendar iCal = new iCalendar(); 
	iCal.ContentTransferEncoding = MailEncoding.Bit7;

	//create an start and end date, tomorrow at 10am, for 1 hr.
	DateTime tomorrow = DateTime.Now.AddDays(1);
	DateTime start = new DateTime( tomorrow.Year, tomorrow.Month, tomorrow.Day, 10,0,0);
	DateTime end = start.AddHours( 1 );

	//set some basic properties
	iCal.Event.Summary.Text = "this is a test ical"; 
	iCal.Event.Location.Text = "100 main conf room"; 
	iCal.Event.DateStart.Date = start; 
	iCal.Event.DateEnd.Date = end; 

	iCal.TimeZone.Format = TimeZoneFormat.ConvertToUTC;

	return iCal;
}

Example 1
This example demonstrates how to create a standard iCalendar enabled email. This code example will create the iCalender object, and add it to the EmailMessage object. Internally, aspNetEmail actually adds the iCalender to the internal body parts collection. The resulting email will actually have 3 body parts:

a)A Plain Text body part
b)A Html Body Part
c)An iCalendar Body Part

Here is a code example that demonstrates this behavior, along with a screenshot of the resulting email.

public void NormaliCalendar()
{
	//create a normal EmailMessage object
	//set some basic properties
	EmailMessage msg = new EmailMessage( "127.0.0.1" );
	msg.From = "me@example.com";
	msg.To = "you@example.com";
	msg.Subject = "ical test";

	//create the iCalendar object
	iCalendar iCal = CreateiCal(); 

	//add the iCalendar to the EmailMessage object
	msg.AddCalendar( iCal );

	//send it
	//msg.Send();
}

Notice that in that screenshot, we can have a nicely formatted, easily readable body. By default, aspNetEmail will create this from the properties of the iCalendar. However, the developer can over ride this behavior, and create their own friendly body.

Example 2
Some mail systems don't like to have a 3rd body part. This is typically a smaller subset, has a specialized situation. Instead, these mail systems like to have the entire body of the email actually be the iCalendar. The limitation of this is that some mail systems don't know how to interpret the email message.  This may or may not affect your situation. If you need to have the iCalendar object be the email body, the following code example demonstrates this behavior. Also, found below, is a screenshot of an email that doesn't know how to render this type of format.

public void iCalAsBody()
{
	//create a normal EmailMessage object
	//set some basic properties
	EmailMessage msg = new EmailMessage( "127.0.0.1" );
	msg.From = "me@example.com";
	msg.To = "you@example.com";
	msg.Subject = "ical test";

	//create the iCalendar object
	iCalendar iCal = CreateiCal(); 

	//set the body of the EmailMessage object itself.
	msg.ContentType = "text/Calendar;\r\n\tMethod=\"REQUEST\";";
	msg.Body = 	iCal.ToString( iCalendarType.iCal );

	//send it
	//msg.Send();

}

Notice that in this screenshot, the email is not easily reable. Also, this iCalendar appears to be missing. This is because the email client (Outlook Express in this example) doesn't know how to render an email, where the body is an iCalender.

Example 3
The 3rd example attempts to offer a combination of both Example 1 and Example 2. By adding a "name" parameter to the Content-Type value, we can get some mail clients to alternatively render the body of the email as an attachment. There really isn't an attachment, but the mail client thinks there is. This allows some mail clients to at least add the iCalendar to their calendaring system.

Below is a code example that demonstrates this, along with a screenshot of the resulting email.

public void iCalAsBodyAndAttachment()
{
	//create a normal EmailMessage object
	//set some basic properties
	EmailMessage msg = new EmailMessage( "127.0.0.1" );
	msg.From = "me@example.com";
	msg.To = "you@example.com";
	msg.Subject = "ical test";

	//create the iCalendar object
	iCalendar iCal = CreateiCal(); 

	//set the body of the EmailMessage object itself.
	//however, the additional Name parameter tricks the 
	//mail client into thinking there is an attachment
	msg.ContentType = "text/Calendar;\r\n\tMethod=\"REQUEST\";\r\n\tName=\"meeting.ics\"";
	msg.Body = 	iCal.ToString( iCalendarType.iCal );
	//send it
	//msg.Send();

}

 

Although this email isn't as pretty, by adding the "Name" parameter, it allows the mail client to present the user with an iCal that can be used.

As always, if anyone has any questions, feel free to contact me.

Thanks!
Dave Wanta

 

 

Testimonial

Many thanks again for your help! "

Ian Blackburn

Read more testimonials
ListNanny aspNetDNS aspNetEmail aspNetPOP3 aspNetMX aspNetMIME aspNetPING aspNetTraceRoute aspNetIMAP aspNetMHT