I have created a new MailTo extension method for the Process class which just fills the Process with a new ProcessStartinfo which contains the required mailto arguments. I have created a method called FormatMailToArgument (Right at the end) which converts control characters to their Url Encoded equivelants and have tested this and it works but is there a better way of doing this?
/// <summary>
/// <see cref="Process"/> extension methods.
/// </summary>
public static class Processes
{
#region MailTo
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="mailMessage">The mail message.</param>
public static void MailTo(this Process process, MailMessage mailMessage)
{
MailTo(
process,
mailMessage.To.ToDelimetedString(),
mailMessage.CC.ToDelimetedString(),
mailMessage.Bcc.ToDelimetedString(),
mailMessage.Subject,
mailMessage.Body);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses.</param>
public static void MailTo(this Process process, IEnumerable<string> to)
{
MailTo(
process,
to.ToDelimetedString(Character.SemiColon),
null,
null,
null,
null);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses.</param>
/// <param name="subject">The email subject.</param>
public static void MailTo(this Process process, IEnumerable<string> to, string subject)
{
MailTo(
process,
to.ToDelimetedString(Character.SemiColon),
null,
null,
subject,
null);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses.</param>
/// <param name="subject">The email subject.</param>
/// <param name="body">The email body.</param>
public static void MailTo(
this Process process,
IEnumerable<string> to,
string subject,
string body)
{
MailTo(
process,
to.ToDelimetedString(Character.SemiColon),
null,
null,
subject,
body);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses.</param>
/// <param name="cc">The Cc email addresses.</param>
/// <param name="subject">The email subject.</param>
/// <param name="body">The email body.</param>
public static void MailTo(
this Process process,
IEnumerable<string> to,
IEnumerable<string> cc,
string subject,
string body)
{
MailTo(
process,
to.ToDelimetedString(Character.SemiColon),
cc.ToDelimetedString(Character.SemiColon),
null,
subject,
body);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses.</param>
/// <param name="cc">The Cc email addresses.</param>
/// <param name="bcc">The Bcc email addresses.</param>
/// <param name="subject">The email subject.</param>
/// <param name="body">The email body.</param>
public static void MailTo(
this Process process,
IEnumerable<string> to,
IEnumerable<string> cc,
IEnumerable<string> bcc,
string subject,
string body)
{
MailTo(
process,
(to == null) ? null : to.ToDelimetedString(Character.SemiColon),
(cc == null) ? null : cc.ToDelimetedString(Character.SemiColon),
(bcc == null) ? null : bcc.ToDelimetedString(Character.SemiColon),
subject,
body);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses.</param>
/// <param name="cc">The Cc email addresses.</param>
/// <param name="bcc">The Bcc email addresses.</param>
/// <param name="subject">The email subject.</param>
/// <param name="body">The email body.</param>
/// <param name="attachmentPath">The attachment file path.</param>
public static void MailTo(
this Process process,
IEnumerable<string> to,
IEnumerable<string> cc,
IEnumerable<string> bcc,
string subject,
string body,
string attachmentPath)
{
MailTo(
process,
(to == null) ? null : to.ToDelimetedString(Character.SemiColon),
(cc == null) ? null : cc.ToDelimetedString(Character.SemiColon),
(bcc == null) ? null : bcc.ToDelimetedString(Character.SemiColon),
subject,
body,
attachmentPath);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses delimeted by a semi-colon.</param>
/// <param name="cc">The Cc email addresses delimeted by a semi-colon.</param>
/// <param name="bcc">The Bcc email addresses delimeted by a semi-colon.</param>
/// <param name="subject">The email subject.</param>
/// <param name="body">The email body.</param>
public static void MailTo(this Process process, string to, string cc, string bcc, string subject, string body)
{
MailTo(process, to, cc, bcc, subject, body, null);
}
/// <summary>
/// Populates the process with mailto <see cref="ProcessStartInfo"/>. You may leave any
/// argument as <c>null</c> if not needed.
/// </summary>
/// <param name="process">The process.</param>
/// <param name="to">To email addresses delimeted by a semi-colon.</param>
/// <param name="cc">The Cc email addresses delimeted by a semi-colon.</param>
/// <param name="bcc">The Bcc email addresses delimeted by a semi-colon.</param>
/// <param name="subject">The email subject.</param>
/// <param name="body">The email body.</param>
/// <param name="attachmentPath">The attachment file path. Note: this will not work in some
/// email applications.</param>
public static void MailTo(
this Process process,
string to,
string cc,
string bcc,
string subject,
string body,
string attachmentPath)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(Uri.UriSchemeMailto + Character.Colon);
stringBuilder.Append(FormatMailToArgument(to));
if (!string.IsNullOrEmpty(cc) || !string.IsNullOrEmpty(bcc) ||
!string.IsNullOrEmpty(subject) || !string.IsNullOrEmpty(body) ||
!string.IsNullOrEmpty(attachmentPath))
{
stringBuilder.Append(Character.Question);
List<string> arguments = new List<string>();
if (!string.IsNullOrEmpty(subject))
{
arguments.Add("subject=" + FormatMailToArgument(subject));
}
if (!string.IsNullOrEmpty(body))
{
arguments.Add("body=" + FormatMailToArgument(body));
}
if (!string.IsNullOrEmpty(cc))
{
arguments.Add("CC=" + FormatMailToArgument(cc));
}
if (!string.IsNullOrEmpty(bcc))
{
arguments.Add("BCC=" + FormatMailToArgument(bcc));
}
if (!string.IsNullOrEmpty(attachmentPath))
{
arguments.Add("attachment=" + FormatMailToArgument(attachmentPath));
}
stringBuilder.Append(arguments.ToDelimetedString(Character.Ampersand));
}
process.StartInfo = new ProcessStartInfo(stringBuilder.ToString());
}
#endregion
#region Methods
/// <summary>
/// Formats the mailto argument. Converts <![CDATA['%', '&', ' ', '?', '\t', '\n']]> to their
/// hexadecimal representation.
/// </summary>
/// <param name="argument">The argument.</param>
/// <returns>The formatted argument.</returns>
private static string FormatMailToArgument(string argument)
{
return argument.
Replace(Character.Percent.ToString(), "%25").
Replace(Character.Ampersand.ToString(), "%26").
Replace(Character.Colon.ToString(), "%3A").
Replace(Character.HorizontalTab.ToString(), "%0D").
Replace(Character.NewLine.ToString(), "%0A").
Replace(Character.Question.ToString(), "%3F").
Replace(Character.Quote.ToString(), "%22").
Replace(Character.Space.ToString(), "%20");
}
#endregion
}
If you mean is there are more efficient way to escape your email addresses then yes you could use the System.Uri class.
string escapedAddress = Uri.EscapeUriString("mailto:joe blogg's\r\[email protected]");
Console.WriteLine(escapedAddress);
Output:
mailto:joe%20blogg's%0D%[email protected]
You'll notice in my example the single quote character doesn't get escaped but that's because it's not required to be in email addresses.
As far as the general approach you have used I don't see why you would add an extension method to the Process class. To send an email and have all the address escaping. attachments, server authentication etc. etc. taken care of why not just use the System.Net.Mail classes?