Email creation processes tend to run as unattended services, so to keep things simple I have created a simple .NET console app. You could run this as a SharePoint timer task, but the basic idea would apply equally well to a service or an interactive app or web form.
In the main method we get some data, which in my simple app is just being read in from an xml file, but you could obviously use a database call, or SharePoint list, etc. Once we have the data, we bind it to a DataGrid WebControl. At that point, any aspect of the DataGrid is available and we set some colors and properties to allow it to render nicely. I put the DataGrid and any other controls we want to send in the email into a Panel's control collection, then render the Panel to the body of the email.
You'll need to add a reference to System.Web to get access to the WebControls. I've also added a reference to System.Drawing to be able to set colors on the DataGrid.
As you see the key function is ControlToHtml which renders the panel to a string, with all of the accompanying built in WebControl UI goodness. This just takes a few lines of code:
static void Main(string[] args)
{
DataTable dataTable = GetData();
DataGrid dg = new DataGrid();
TableItemStyle altStyle = new TableItemStyle();
altStyle.BackColor = Color.LightGray;
dg.HeaderStyle.Font.Bold = true;
dg.HeaderStyle.BackColor = System.Drawing.Color.LightSteelBlue;
dg.AlternatingItemStyle.BackColor = System.Drawing.Color.LightGray;
dg.DataSource = dataTable;
dg.DataBind();
Panel MainPanel = new Panel();
MainPanel.Style.Add("padding", "1em");
MainPanel.Style.Add("margin", "1em");
MainPanel.HorizontalAlign = HorizontalAlign.Center;
MainPanel.Controls.Add(dg);
MainPanel.Controls.Add(new LiteralControl("<br />
Prices collected " +
DateTime.Now.ToShortDateString()));
string EmailTo = "davis@rdacorp.com";
string EmailFrom = "davis@rdacorp.com";
string EmailSubject = "Daily stock price";
string title = "Today's Prices";
string body = ControlToHtml(MainPanel);
SendEmail(EmailTo, EmailFrom, EmailSubject, body, title);
}
public static string ControlToHtml(WebControl theControl)
{
StringBuilder SB = new StringBuilder();
StringWriter SW = new StringWriter(SB);
HtmlTextWriter htmlTW = new HtmlTextWriter(SW);
theControl.RenderControl(htmlTW);
return SB.ToString();
}
I want to include my SendEmail function only because it has some simple code you'll need if your SMTP Server needs authentication:
Finally, here's a screen shot of the email that went out.
public static string SendEmail(string EmailTo, string EmailFrom, string SubjectText, string BodyText, string Title)
{
string SMTPServer = ConfigurationSettings.AppSettings["SMTPServer"];
MailMessage mailmessage = new MailMessage();
mailmessage.From = EmailFrom;
mailmessage.To = EmailTo;
mailmessage.Subject = SubjectText;
mailmessage.Body = BodyText;
mailmessage.BodyEncoding = Encoding.UTF8;
mailmessage.BodyFormat = MailFormat.Html;
if (bool.Parse(ConfigurationSettings.AppSettings["MailAuthenticationRequired"]))
{ // true if authentication required, false if anonymous sending is allowed.
mailmessage.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] = 1;
mailmessage.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"] = ConfigurationSettings.AppSettings["MailUserName"];
mailmessage.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"] = ConfigurationSettings.AppSettings["MailPassword"];
}
SmtpMail.SmtpServer = SMTPServer;
string Result = "";
SmtpMail.Send(mailmessage);
Result = "Mail accepted for delivery.\r\n";
return Result;
}

It should be possible to render an entire Page control to an email, so a web page could do double duty as both email and web. If there's a need for this, let us know and we'll look into a second part for this article.


1 comments:
Good post, thanks.
I can totally read the "blurred" e-mail though ... :-)
Post a Comment