Tuesday, January 10, 2012

Creating Mail Scheduler in C#

Today while developing a page for sending mail, I was asked to create a scheduler in c# that would send mail on periodically.
I did an R&D for that and resolved the problem creating WindowServices in c#.

Its easy just go thr these steps;

1.Open Visual Studio.net > Select New Project

2.Select Windows Service and give Name as 'MailScheduler' and Click Ok.

3.Right Click the Design and Select Properties and give the Name and ServiceName as

'ScheduleMail' and set AutoLog to 'True'

4.Right Click the Design and select View Code and

Select Project > Add Reference > Select System.Web >Press Ok

5.Now add the following to your code

using System.Web.Mail;

In static void Main()

ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new ScheduleMail()
};
ServiceBase.Run(ServicesToRun);

6. Edit the following code in onstart()

protected override void OnStart(string[] args)
{
eventLogSimple.WriteEntry("ScheduleMail service started at :" + DateTime.Now.ToShortDateString().Trim());
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 30000; //1000 for 1sec so 1hr has 3600sec and 1day has 3600*24 sec
//i.e 86400 sec
//hence for this in ms = 86400000(for one day)
timer.AutoReset = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_TimeElapsed);
// timer_TimeElapsed();
timer.Enabled = true;
eventLogSimple.WriteEntry("mail sent successfully at :" + DateTime.Now.ToShortDateString().Trim());

}

Add following method
private static void timer_TimeElapsed(object source, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.ToShortDateString().Trim() == "1/10/2012")
{

MailMessage msg = new MailMessage();
msg.To = "toaddress here..";
msg.From = "from address here..";
msg.Subject = "Test Scheduler";
msg.BodyFormat = MailFormat.Text;
msg.Body = "this is a scheduled mail from mail scheduler..";
msg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"] = "servernamehere...";
msg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"] = 25;
msg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 2;
msg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] = 1;

////Most of the times the @domain is necessary with the username
msg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"] = "username here..";
msg.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"] = "password here..";
SmtpMail.SmtpServer = "servername here..";
SmtpMail.Send(msg);
}
}

7.Go to Design,right click and Select Add Installer ,you will notice two controls

serviceProcessInstaller1,serviceInstaller1

8.Select serviceProcessInstaller1 and go to its properties and change the Account

type to 'Local System'

9. Select serviceInstaller1 and go to its properties and change DisplayName and

ServiceName to 'ScheduleMail' and make the StartType to 'Automatic'

10.Build the Solution

11.Open the Visual Studio .Net Command Prompt and give the path of application

for example C:\bin\Debug and then type InstallUtil MailScheduler.exe

to uninstall, InstallUtil /u MailScheduler.exe

15. After Installation ,right click My Computer and

Select 'Manage'

and Select 'Service and Applications'

and in that Select 'Services'

Select ScheduleMail' and start the Service.

Good Luck!!!

Wednesday, January 4, 2012

Sending Mail Using System.Web.Mail/System.Net.Mail with Attachments

Hello friends,
Today also I did a lot of R&D for sending mail using System.Web.Mail for .Net 1.1.
Many of you are seeing this post because while trying sending mail in 1.1 you are unable to do so.

If you thought that it was a serious shortcoming that .Net framework 1.1 wasn't able to send email through SMTP servers that used authentication, you are in grave ignorance. On the surface of it, yes, you cannot send an email with the standard System.Web.Mail.MailMessage class; but you can of course play tricks on the Exchange server (yeah, that's what I get out of it that this things works only on an Exchange server) to make it authenticate you.

There is a namespace called http://schemas.microsoft.com/cdo/configuration that does those funny (and highly interesting) tricks.

Here both the version for you. Send mail either using System.Web.Mail or System.

protected void SendMail()
{
//step 1:
MailMessage msg = new MailMessage();
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
//System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
string smtpServer = "";

//step 2:
msg.To = _emailIdsToSend;
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
//mail.To.Add(_emailIdsToSend);

//step 3:
msg.From = "dummyfrom@dummy.com";
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
// mail.From = new System.Net.Mail.MailAddress("dummyfrom@dummy.com");
string date = DateTime.Now.ToString("dd-MM-yyyy");

//step 4:
msg.Subject = "Test Mail on : "+date;
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
//mail.Subject = "Test Mail on : " + date;

//step 5:
msg.Body = "some text goes here...";
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
//mail.Body = "some text goes here..";

//step 6:
//attachments here...
MailAttachment attachment = new MailAttachment(finalFileToAttach);
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
//System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(finalFileToAttach);

//step 7:
msg.Attachments.Add(attachment);
//Either use above if you are using System.Web.Mail or uncomment below one if using System.Net.Mail
//mail.Attachments.Add(attachment);

//step 8:
msg.BodyFormat = MailFormat.Html;
//Either use above if you are using System.Web.Mail or uncommet below one if using System.Net.Mail
//mail.IsBodyHtml = true;

//step 9:credentials
msg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"] = "yoursmtpserverhere..";
msg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"] = 25;
msg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 2;
msg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] = 1;
////Most of the times the @domain is necessary with the username
msg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"] = "usernamewithdomainehere..";
msg.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"] = "passwordhere..";
//If only the server uses SSL, in this case, the smtpserverport field would be different too
message.Fields["http://schemas.microsoft.com/cdo/configuration/smtpusessl"] = true;
if (ConfigurationSettings.AppSettings["SMTPServerName"].ToString() != null && ConfigurationSettings.AppSettings["SMTPServerName"].ToString() != "")
SmtpMail.SmtpServer = ConfigurationSettings.AppSettings["SMTPServerName"].ToString().Trim();
//.net either use above if you are using System.Web.Mail or uncommet below one if using System.Net.Mail
//System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
//client.Host = "yoursmtpserverhere..";
//client.Credentials=new System.Net.NetworkCredential("usernamewithdomainhere", "password here");
//client.Port = 25;
//step 10: Send Mail
try
{

SmtpMail.Send(msg);
//.net either use above if you are using System.Web.Mail or uncommet below one if using System.Net.Mail
//client.Send(mail);
}
finally
{
//mail.Dispose();
msg = null;
attachment = null;

}
}

Tuesday, January 3, 2012

Writing CSV To File

protected string WriteToCSVForMail(DataTable dt, string fileName, NameValueCollection nvcCriteria)
{
//file name should be the full path of the file.
string fileNameWithExt = fileName + ".csv";
FileInfo fileToWorkOn = new FileInfo(fileNameWithExt);
//check if file exist, if not create one
if (!fileToWorkOn.Exists)
{
FileStream createdFile = fileToWorkOn.Create();
createdFile.Close();
fileToWorkOn = new FileInfo(fileNameWithExt);
}
StreamWriter writer = fileToWorkOn.CreateText();
//trying to write the criteria in downloaded csv file.
writer.Write("Following Criterion is used to generate this Report");
writer.Write(Environment.NewLine);
writer.Write("FromDate : " + nvcCriteria["FromDate"]);
writer.Write(Environment.NewLine);
writer.Write("ToDate : " + nvcCriteria["ToDate"]);
writer.Write(Environment.NewLine);
writer.Write("QuoteId : " + nvcCriteria["QuoteId"]);
writer.Write(Environment.NewLine);
writer.Write("QuoteStatus : " + nvcCriteria["StatusText"]);
writer.Write(Environment.NewLine);
writer.Write("Product : " + nvcCriteria["ProductText"]);
writer.Write(Environment.NewLine);
writer.Write("AccessType : " + nvcCriteria["AccessText"]);
writer.Write(Environment.NewLine);
foreach (DataColumn column in dt.Columns)
{

writer.Write(column.ColumnName + ",");

}

writer.Write(Environment.NewLine);
foreach (DataRow row in dt.Rows)
{

for (int i = 0; i < dt.Columns.Count; i++)
{

string outputS = EscapeCsvField(row[i].ToString());
writer.Write(outputS + ((i < dt.Columns.Count - 1) ? "," : Environment.NewLine));

}
}
writer.Close();
return fileNameWithExt;
//properties of FileInfo class
//Console.WriteLine("Full name of the file we are working on : " + fileToWorkOn.FullName);
//Console.WriteLine("Full name of the directory file is on : " + fileToWorkOn.DirectoryName);
//fileToWorkOn.CopyTo("d:\\test2copy.txt");
//fileToWorkOn.Delete();
}

use same EscapeCSVField method I used in earlier post.

Enjoy Coding!

Exporting DataTable To CSV File

Hi All
Once again I feel if you have tried writing to Csv, You must have faced problem of delimiter collision.
Here is the solution:
protected void ExportToCSV(DataTable dataTable, string fileName, NameValueCollection nvcCriteria)
{

HttpContext context = HttpContext.Current;

context.Response.Clear();

//trying to write the criteria in downloaded csv file.
context.Response.Write("Following Criterion is used to generate this Report.");
context.Response.Write(Environment.NewLine);
context.Response.Write("FromDate : " + nvcCriteria["FromDate"]);
context.Response.Write(Environment.NewLine);
context.Response.Write("ToDate : " + nvcCriteria["ToDate"]);
context.Response.Write(Environment.NewLine);
context.Response.Write("QuoteId : " + nvcCriteria["QuoteId"]);
context.Response.Write(Environment.NewLine);
context.Response.Write("QuoteStatus : " + nvcCriteria["StatusText"]);
context.Response.Write(Environment.NewLine);
context.Response.Write("Product : " + nvcCriteria["ProductText"]);
context.Response.Write(Environment.NewLine);
context.Response.Write("AccessType : " + nvcCriteria["AccessText"]);
context.Response.Write(Environment.NewLine);
foreach (DataColumn column in dataTable.Columns)
{

context.Response.Write(column.ColumnName + ",");

}

context.Response.Write(Environment.NewLine);



foreach (DataRow row in dataTable.Rows)
{

for (int i = 0; i < dataTable.Columns.Count; i++)
{

string outputS = EscapeCsvField(row[i].ToString());
//Response.Write(row[i].ToString());
context.Response.Write(outputS + ((i < dataTable.Columns.Count - 1) ? "," : Environment.NewLine));

}

//context.Response.Write(Environment.NewLine);

}

context.Response.ContentType = "text/csv";

context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName + ".csv");

context.Response.End();

}

Below is the EscapeCSVField method for handling delimiter collision.
private string EscapeCsvField(string sFieldValueToEscape)
{

// since we delimit values with a comma, we need to escape commas that are

// actually in the value to escape. We do this by putting a (") quote at

// the front and end of the string.

if (sFieldValueToEscape.Contains(","))
{

// if the string we are escaping already has a (") quote in it, we have to

// 'escape the escape character' by putting double quotes in it's place.

if (sFieldValueToEscape.Contains("\""))
{

return "\"" + sFieldValueToEscape.Replace("\"", "\"\"") + "\"";

}

else
{

// there are no quotes in this string so just escape it by wrapping it in

// quotes.

return "\"" + sFieldValueToEscape + "\"";

}

}

else
{

// There are no commas in this string so just return it as is

return sFieldValueToEscape;

}

}

Happy Programming!