I have created a project very similar to this in the past and opted to use the MailItem.HTMLBody property instead of fighting with object placement.
In my case I was constructing a data grid, but something similar can be constructed to take in your URL data. NOTE: This was early in my development days and the code may need some refactoring, but for a copy and paste from the past, it isn't too bad I hope. I have also excluded some unnecessary information from this post, but the most important bits are contained herein.
In order to assemble the body of the email, this method creates a StringBuilder and constructs the HTML document piece by piece.
public string ConstructBody(DataTable dataTable)
{
StringBuilder bodyStringBuilder = new StringBuilder();
// Creates the HTML code, constructs body, Constructs table, defines table border.
bodyStringBuilder.AppendLine("<html>");
bodyStringBuilder.AppendLine(Tab + "<body>");
bodyStringBuilder.AppendLine(Tab + Tab + "<table>");
bodyStringBuilder.AppendLine(Tab + Tab + "<table border='2' bgcolor:#DDDDDD bordercolor:black>");
// Column headers - Style defined.
bodyStringBuilder.Append(Tab + Tab + Tab + "<tbody align='center' style='font-family:verdana; color:#000000; font-size:14;background-color:#9DB9C8'>");
bodyStringBuilder.Append(Tab + Tab + Tab + "<tr>");
// Column Headers - Named
foreach (DataColumn dc in dataTable.Columns)
{
bodyStringBuilder.AppendFormat("<th>{0}</th>", dc.ColumnName);
}
// End of Column Header Creation
bodyStringBuilder.AppendLine("</tr>");
// Empty data rows created and filled by another foreach loop
int drColorSwitch = 1;
foreach (DataRow dr in dataTable.Rows)
{
if (IsOdd(drColorSwitch))
{
bodyStringBuilder.Append(Tab + Tab + Tab + Tab + "<tbody align='center' style='font-family:verdana;background-color=#DDDDDD; color:#000000; font-size:14 '>");
}
else
{
bodyStringBuilder.Append(Tab + Tab + Tab + Tab + "<tbody align='center' style='font-family:verdana;background-color=#BDD0D9; color:#000000; font-size=14 '>");
}
bodyStringBuilder.Append(Tab + Tab + Tab + "<tr>");
drColorSwitch ++;
// Fills the data.
foreach (DataColumn dc in dataTable.Columns)
{
string cellValue = dr[dc] != null ? dr[dc].ToString() : "";
bodyStringBuilder.AppendFormat("<td>{0}</td>", cellValue);
}
// Closes out each datarow
bodyStringBuilder.AppendLine("</tr>");
} // End of the datarow creation functions
// Closes the table, closes the body, and finally ends the HTML code for the body of the email.
bodyStringBuilder.AppendLine(Tab + Tab + "</table>");
bodyStringBuilder.AppendLine(Tab + "</body>");
bodyStringBuilder.AppendLine("</html>");
return bodyStringBuilder.ToString(); // Finally - returns value of SB
}
Finally, in the MailReport method I create the email message and call Send();
public void MailReport(DataTable datatable,string[] recipients,string subject, string headertext, string reporttitle, bool includedate, bool includefiles, string[] filelist, bool isEncrypted)
{
// Creates instance of Header and Body Construction Classes
HeaderConstruction headerConstruction = new HeaderConstruction();
BodyConstruction bodyConstruction = new BodyConstruction();
Outlook.Application oApp = new Outlook.Application();
Outlook.MailItem oMsg = oApp.CreateItem(Outlook.OlItemType.olMailItem);
foreach (string recipient in recipients)
{
oMsg.Recipients.Add(recipient);
}
if(isEncrypted)
{
// If caller indicates that message should be encrypted, system will add secured flag to subject
oMsg.Subject = "<secure> " + subject;
}
else
{
// Else, message will transmit without security flag
oMsg.Subject = subject;
}
// introduces the body table
oMsg.HTMLBody = headerConstruction.ConstructHeader(headertext,reporttitle, includedate) + bodyConstruction.ConstructBody(datatable);
// Includes files in output message if requested
if (includefiles)
{
foreach (string path in filelist)
{
oMsg.Attachments.Add(path);
}
}
// Send
oMsg.Send();
}