Thứ Ba, 31 tháng 3, 2009

Send Emails using windows services in C# .net

Windows Services and the Application Scheduler are two different ways of achieving much the same thing. I will assume that you are referring to Windows Services.

First of all there is a question of Architecture. Similar to web applications where you want a thin UI and a separate class project for all data access routines ect., you should plan on on putting all the sending logic into a class project. To aid monitoring, I suggest that you set up some parameter tables (you could use the parameter tables in http://www.CodePlex.Com/CommonParam).

In a date Parameter table, you could have rows for:

  • Heatbeat
  • Last mail sent
  • Last error detected
In a boolean parameter table, you could have
  • Mail to be sent (when false the queue is not polled)

When you have the action logic settled it is then simple to have a Windows Service trigger the action. For some examples of Windows Services, please see:

Sending E-Mail to Multiple Users from a Database

The Question:

Anyone done this yet... I am interested in making a mail list system that will query database for email address for users and send out a generic e-mail.

The Answer:

This can be done using the System.Web.Mail namespace. This namespace has two classes you will use to accomplish this, MailMessage and SmtpMail. The MailMessage class represents a single e-mail message, and the SmtpMail class is used to send the MailMessage using the configured SMTP server.

The following code should be used in a method or event handler where the e-mail address are retreived from a database. Here you loop through the e-mail addresses, changing the "To" property of the MailMessage and sending it.

[VB]
'cmd is a SqlCommand that gets email addresses

Dim _r As SqlDataReader = cmd.ExecuteReader()
Dim _mm As System.Web.Mail.MailMessage = New System.Web.Mail.MailMessage()
_mm.From = "me@mydomain.com"
_mm.Body = "This is my e-mail message"
While _r.Read()
_mm.To = _r("Email")
System.Web.Mail.SmtpMail.Send(_mm)
Loop

[C#]
//cmd is a SqlCommand that gets email addresses

SqlDataReader _r = cmd.ExecuteReader();
System.Web.Mail.MailMessage _mm = new System.Web.Mail.MailMessage();
_mm.From = "me@mydomain.com";
_mm.Body = "This is my e-mail message";
while ( _r.Read() )
{
_mm.To = _r["Email"];
System.Web.Mail.SmtpMail.Send(_mm);
}

*Note: This thype of function is limited to the timeout settings of a Web request, so it will only work for up to around 1,000 e-mail addresses.

IIS SMTP Service

Note: this article is only suitable for ANSMTP 6.4 or later.
For ANSMTP 6.3 or earlier version, please click here.

Important notice: * We strongly recommand the developer use the ANSMTP 7.0 + EASendMail Service instead of IIS SMTP service.

Introduction

IIS SMTP Service is a high performance SMTP server on Windows NT/2000/XP. We can use it to send email easily with ANSMTP. This tutorial shows how to install IIS SMTP service and program with it.

  • How to can send email by IIS SMTP Service

  • How to use ESMTP authentication

  • How to send email by pickup path of IIS SMTP Service

  • How to handle undeliverable email

Installation and Deployment

You should download the ansmtp installer and install it on your machine at first. If you want to distribute or deploy ansmtp without ansmtp installer, please click here to learn more.

Install IIS SMTP Service

You can install IIS on Windows 2000/XP as follows: "Control Panel->Add/Remove Programs->Windows Components->Internet Information Service->SMTP Service". For Windows NT user, you can install it from Option Pack 4.0 of Windows NT. After installed, you can start it from "Control Panel->Administrative Tools->Internet Information Service".

Send Email by IIS SMTP Service

Now you can send email by IIS SMTP Service with the following code:

[ASP]

<% Set oSmtp = Server.CreateObject("AOSMTP.Mail") oSmtp.ServerAddr = "127.0.0.1" 'computer ip address. oSmtp.FromAddr = "test@adminsystem.net" oSmtp.AddRecipient "Support Team", "support@adminsystem.net", 0 oSmtp.Subject = "Test" oSmtp.BodyText = "Hello, this is a test...." If oSmtp.SendMail() = 0 Then Response.Write "Message delivered!" Else Response.Write oSmtp.GetLastErrDescription() End If %>

ESMTP authentication/Trusted IP Addresses

The default setting of IIS Smtp service may cause failure in sending email ("Error with sending recipient"). Here are two solutions to the problem.

Enable ESMTP authentication of IIS SMTP Service

1. "Control Panel->Administrative Tools->Internet Information Service->Default SMTP Virtual Server->Properties->Access->Authentication. ". Check the BASIC Authentication.

2. "Control Panel->Administrative Tools->Internet Information Service->Default SMTP Virtual Server->Properties->Access->Relay ". Check the "Allow all computers which successfully authentication to relay ..."

You also need to change your code like this:

[ASP]

<% Set oSmtp = Server.CreateObject("AOSMTP.Mail") oSmtp.ServerAddr = "127.0.0.1" 'computer ip address. oSmtp.FromAddr = "test@adminsystem.net" oSmtp.AddRecipient "Support Team", "support@adminsystem.net", 0 oSmtp.Subject = "Test" oSmtp.BodyText = "Hello, this is a test...." oSmtp.UserName = "administrator" 'any valid user of current machine. oSmtp.Password = "ad1234" 'password of this user If oSmtp.SendMail() = 0 Then Response.Write "Message delivered!" Else Response.Write oSmtp.GetLastErrDescription() End If %>

Then your application can send email to any email address without error.

Trusted IP Addresses

If you don't want to do ESMTP authentication, you can add the IP address of your computer to Relay IP Addresses List of IIS SMTP Service.

"Control Panel->Administrative Tools->Internet Information Service->Default SMTP Virtual Server->Properties->Access->Relay" Check "Only the list below" and add your computer IP address to this list. Any email sent from this IP address will be accepted by IIS SMTP Service even without user authentication.

Send Email by Pickup Patch/Mail Queuing

After installed IIS SMTP Service, there is a directory named "Pickup" ("C:\Inetpub\mailroot\Pickup"). IIS SMTP Service keeps on monitoring this folder, once an email is saved in this directory, IIS SMTP Service will queue this email and send it automatically in background.

The following code demonstrates how to send email by pickup path of IIS SMTP Service.

[ASP]

Dim oSmtp, pickupPath
Set oSmtp = Server.CreateObject("AOSMTP.Mail")
pickupPath = "c:\inetpub\mailroot\pickup"

oSmtp.FromAddr = "test@msn.com"
oSmtp.AddRecipient "support team", "support@adminsystem", 0
oSmtp.Subject = "test subject"
oSmtp.BodyText = "test body"

If oSmtp.SaveMailEx( pickupPath ) = 0 Then
Response.Write "Email queued"
Else
Response.Write "SaveMailEx method failed"
End If

We strongly recommend you send email in ASP/ASP.NET application in this way.

Handle Undeliverable Email

How does IIS SMTP Service manage undeliverable emails? It saves those emails to specified folder ("C:\Inetpub\mailroot\Badmail"). If you want to receive those undeliverable emails, you can add your email address in "Control Panel->Administrative Tools->Control Panel->Administrative Tools->Internet Information Service->Default SMTP Virtual Server->Properties->Messages"

More Summary

If an email couldn't be sent to specified email address in first trial, IIS SMTP Service would move it to "Queue" folder and IIS SMTP Service would keep on retrying later until expired. You can set expiration timeout of IIS SMTP Service in "Control Panel->Administrative Tools->Control Panel->Administrative Tools->Internet Information Service->Default SMTP Virtual Server->Properties->Delivery"

Free Email Support

Not enough? Please contact our technical support team.

Support@EmailArchitect.NET
VIP@EmailArchitect.NET(Registered User)

Remarks
We usually reply emails in 24hours. The reason for getting no response is likely that your smtp server bounced our reply. In this case, please try to use another email address to contact us. Your Hotmail or Yahoo email account is recommended.

Sending Emails in Asp.net

Introduction:

Microsoft.NET framework provides many rich class libraries which makes the life of developer easy. Sending emails could not be more simpler than which, is provided in Asp.net. In this article we will see how we can make use of the MailMessage class to send emails with attachments.

Developing the User Interface for our application:

Below is a picture of what the user interface will look like. As you noted that there is a file field control which allows you to attach any file as a mail attachment. There is also a listbox which shows the files that are currently attached with the mail.

You can develop the same interface in any fashion you want. I just developed this since this seems simple.

Code for sending email:

Lets see the code to send an email. This code is executed on the button click control. First of all don't forget to add the

using System.Web.Mail;

namespace which provides the methods and properties for sending an email.

private void Button1_Click(object sender, System.EventArgs e)

{

MailMessage mail = new MailMessage();

mail.To = txtTo.Text;

mail.From = txtFrom.Text;

mail.Subject = txtSubject.Text;

mail.Body = txtBody.Text;

SmtpMail.SmtpServer = "localhost";

SmtpMail.Send(mail);

}

The code you see above is very simple to understand. In the button click event we made the object/instance of the MailMessage class. MailMessage is responsible for sending emails. It also provides several properties and methods. later we assigned several properties.

The line SmtpMail.SmtpServer = "localhost" sets the server for the mail. If you are running the application on your own pc using IIS than your server will be "localhost". If your website is running on the production server you can have different SmtpServer name.

The final line SmtpMail.Send(mail) sends the email to the email address provided. Until now we have not done any coding for the attachments. Lets see how this can be done.

Lets first examine the code for the attach button click event:

// Button used to attach a file

private void Button2_Click(object sender, System.EventArgs e)

{

// gets the file name with the whole path

string attachedFile = File1.PostedFile.FileName;

// Adds the item in the list of attached files

if(attachedFile != "")

{

FileList.Items.Add(attachedFile);

}

}

In this code first we retrieve the whole path of the file from the file field object and assigns it to the attachedFile variable. Next we add the path of the file in our listbox if the path is not null meaning the path is only added when the user attaches a file. After the list is populated with the attachments it will look something like this:

As you see that adding the filename in the listbox control is pretty straightforward and simple. Now lets see how we can do the attachments.

If you like to make a single attachment you can do this easily like this:

mail.Attachments.Add(new MailAttachment(@"C:\myFile.txt"));

As you see making a single attachment is very easy. But in this case we need to make multiple attachments. What we will do is that we will iterate through the listbox and attach every file which is represented by its file path. Lets see the code that can accomplish that.

MailAttachment attachment = null;

try

{

// check to see if there are any attachments or not

if(FileList.Items.Count > 0)

{

foreach(ListItem l in FileList.Items)

{

// Attaches a new attachment contained in the List

Response.Write(l.Text);

attachment = new MailAttachment(l.Text);

mail.Attachments.Add(attachment);

}

}

//mail.Attachments.Add(attachment);

Response.Write("Number of attachments are"+mail.Attachments.Count);

SmtpMail.SmtpServer = "localhost";

SmtpMail.Send(mail);

}

catch(Exception ex)

{

Response.Write(ex.Message);

// Cacthes the exception here

}

Explanation of the Code:

1) First we initialize the MailAttachment object "attachment" to null.

2) Then, in the try-catch block we check that if the listbox has any items or not by using its count property. If the listbox is empty and you try to make an attachment from the listbox item you will get an error specifying that the attachment is invalid.

3) Next, we used the foreach loop to iterate through the listbox and in each iteration we attaches the path contained in the listbox to the MailAttachment.

4) Inside the foreach loop we also add attachments to our mail object.

5) If you are unsure that how many attachments you have in the mail object you can use the property

mail.Attachments.Count

to get the total number of attachments for the current mail object.

6) Until now all the attachments have been made and we just simply set the server name and send the email using the SmtpMail.Send() method.

Problems you might encounter while sending emails

In Visual Studio.NET 2002 sending mail was the same as easy. There are various problems that you might encounter while sending email using Visual Studio.NET 2003. These problems encounter because of the Smtp mail server settings. If you are using your production server for sending emails these problems are not likely to arise but, they do when you use "localhost" to send emails.

Always put a try catch block when sending emails. And also view the inner exception if the exception occurs. When sending email you might get "Could not access CDO message object". This is by far the most annoying error that you will see when sending emails.

There are many scenarios under which this error takes place. Let me explain few ways to resolve the problem.

1) Go to Control Panel -> Administrative tools -> IIS

2) Right Click on the Smtp Server which is at the bottom and select properties.

3) Select the Access Tab

4) Select the Relay option

5) Check the radio button which says use only listed below and add your localhost address to it which is "127.0.0.1".

6) Restart the IIS again and check that if the mail is being sent.

If you are still facing problems please visit http://www.systemwebmail.com/ , this website is devoted to the errors that developers face which sending email using Asp.net.

Conclusion:

As you see in the article that emailing in Asp.net is fairly simple apart from some of the silly errors :). Its always a good idea to save coding and time and develop an email component which can be dragged and dropped on the form and used instantly. Microsoft Visual Studio.NET 2005 which will be released in December 2005 might have an email component already build in so we will not have to write 4-5 lines of code.

This article is also has the project files which you can download and run on your own computer.

Attachments:

Project Files: EmailApplication_azam.zip

Thứ Hai, 30 tháng 3, 2009

How To: Reading and Writing Text Files

Introduction

Text files provide a common denominator format where both people and programs can read and understand. The .NET Framework includes convenience classes that make reading and writing text files very easy. The following sequence outlines the basic steps necessary to work with text files:

  1. Open the file
  2. Read/Write to the file
  3. Close the file

It's that simple. Listing 1 shows how to write text data to a file.

Writing to a Text File

Listing 1: Writing Text Data to a File: TextFileWriter.cs

using System;
using System.IO;

namespace csharp_station.howto
{
class TextFileWriter
{
static void Main(string[] args)
{
// create a writer and open the file
TextWriter tw = new StreamWriter("date.txt");

// write a line of text to the file
tw.WriteLine(DateTime.Now);

// close the stream
tw.Close();
}
}
}

This program creates a text file when it runs. In the directory where the executable program is located, you'll find a file named date.txt. If you view the contents of this file, you'll see the following textual representation of the date and time when the program last ran:

2/15/2002 8:54:51 PM

The first task in Listing 1 is to open the file. This happens by instantiating a StreamWriter class, which returns an object of type TextWriter. The result could have also been assigned to a StreamWriter instance. The StreamWriter was called with a single parameter, indicating the name of the file to open. If this file doesn't exist, the StreamWriter will create it. The StreamWriter also has 6 other constructor overloads that permit you to specify the file in different ways, buffer info, and text encoding. Here's the line that opens the date.txt file:

TextWriter tw = new StreamWriter("date.txt");

Using the TextWriter instance, tw, you can write text info to the file. The example writes the text for the current date and time, using the static Now property of the DateTime class. Here's the line from the code:

tw.WriteLine(DateTime.Now);

When you're done writing to the file, be sure to close it as follows:

tw.Close();

Reading From a Text File

Listing 2 shows how to read from a text file:

Listing 2: Reading Text Data from a File: TextFileReader.cs

using System;
using System.IO;

namespace csharp_station.howto
{
class TextFileReader
{
static void Main(string[] args)
{
// create reader & open file
Textreader tr = new StreamReader("date.txt");

// read a line of text
Console.WriteLine(tr.ReadLine());

// close the stream
tr.Close();
}
}
}

In Listing 2, the text file is opened in a manner similar to the method used in Listing 1, except it uses a StreamReader class constructor to create an instance of a Textreader. The StreamReader class includes additional overloads that allow you to specify the file in different ways, text format encoding, and buffer info. This program opens the date.txt file, which should be in the same directory as the executable file:

Textreader tr = new StreamReader("date.txt");

Within a Console.WriteLine statement, the program reads a line of text from the file, using the ReadLine() method of the Textreader instance. The Textreader class also includes methods that allow you to invoke the Read() method to read one or more character or use the Peek() method to see what the next character is without pulling it from the stream. Here's the code that reads an entire line from the text file:

Console.WriteLine(tr.ReadLine());

When done reading, you should close the file as follows:

tr.Close();

Summary

This article showed how to write text to a file and read it back out. For more details on additional methods, consult the .NET Frameworks reference on the StreamWriter, StreamReader, TextWriter, and Textreader classes.