Skip to content
This repository was archived by the owner on Dec 31, 2024. It is now read-only.
Open

Dev #97

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 72 additions & 27 deletions Examples.xml
Original file line number Diff line number Diff line change
Expand Up @@ -335,40 +335,85 @@
<example>
This example demonstrates how to store a mail message on an IMAP server.
<code>
ImapClient Client = new ImapClient("imap.gmail.com", 993, "My_UsernamMe",
"My_Password", true, AuthMethod.Login);

MailMessage message = CreateSimpleMailMessage();
uint uid = Client.StoreMessage(message);

Console.WriteLine("The UID of the stored mail message is " + uid);

Client.Dispose();
ImapClient Client = new ImapClient("imap.gmail.com", 993, "My_UsernamMe",
"My_Password", AuthMethod.Login, true);

// ...........
MailMessage message = CreateSimpleMailMessage();
uint uid = Client.StoreMessage(message);

// This creates a simple mail message with a text/plain body and a PNG image
// as a file attachment.
// Consult the MSDN website for more details on the System.Net.Mail.Mailmessage class.
static MailMessage CreateSimpleMailMessage() {
MailMessage message = new MailMessage();
Console.WriteLine("The UID of the stored mail message is " + uid);

message.From = new MailAddress("someone@someplace.com");
message.To.Add("john.doe@someplace.com");
Client.Dispose();

message.Subject = "This is just a test!";
message.Body = "This is the text/plain body. An additional HTML body " +
"can optionally be attached as an alternate view";
// ...........

// Add the attachment.
Attachment attachment = new Attachment("some_image.png", "image/png");
attachment.Name = "my_attached_image.png";
message.Attachments.Add(attachment);
// This creates a simple mail message with a text/plain body and a PNG image
// as a file attachment.
// Consult the MSDN website for more details on the System.Net.Mail.Mailmessage class.
static MailMessage CreateSimpleMailMessage() {
MailMessage message = new MailMessage();

return message;
}
</code>
message.From = new MailAddress("someone@someplace.com");
message.To.Add("john.doe@someplace.com");

message.Subject = "This is just a test!";
message.Body = "This is the text/plain body. An additional HTML body " +
"can optionally be attached as an alternate view";

// Add the attachment.
Attachment attachment = new Attachment("some_image.png", "image/png");
attachment.Name = "my_attached_image.png";
message.Attachments.Add(attachment);

return message;
}
</code>
</example>
</ImapClient>
<ImapClient name="StoreMessage2">
<example>
This example demonstrates how to store a mail message on an IMAP server without forcing
the message body to be broken into 76 char lines as per RFC2822 in order to preserve message formatting.
<code>
ImapClient Client = new ImapClient("imap.gmail.com", 993, "My_UsernamMe",
"My_Password", AuthMethod.Login, true);

MailMessage message = CreateSimpleMailMessage();
uint uid = Client.StoreMessage(message, //message to store
false, //mark the message as unseen
null, //use default mailbox
false); //do not force breaking of the message body

Console.WriteLine("The UID of the stored mail message is " + uid);

Client.Dispose();

// ...........

// This creates a simple mail message with a text/plain body and a PNG image
// as a file attachment.
// Consult the MSDN website for more details on the System.Net.Mail.Mailmessage class.
static MailMessage CreateSimpleMailMessage() {
MailMessage message = new MailMessage();

message.From = new MailAddress("someone@someplace.com");
message.To.Add("john.doe@someplace.com");

message.Subject = "This is just a test!";
message.Body = "This is the text/plain body. An additional HTML body " +
"can optionally be attached as an alternate view. " +
"We also need to add a few more words to the message body in order to see " +
"whether they get broken by the StoreMessage procedure.";

// Add the attachment.
Attachment attachment = new Attachment("some_image.png", "image/png");
attachment.Name = "my_attached_image.png";
message.Attachments.Add(attachment);

return message;
}
</code>
</example>
</ImapClient>
</Imap>
</S22>
6 changes: 4 additions & 2 deletions IImapClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ IEnumerable<MailMessage> GetMessages(IEnumerable<uint> uids, FetchOptions option
/// <param name="mailbox">The mailbox the message will be stored in. If this parameter is
/// omitted, the value of the DefaultMailbox property is used to determine the mailbox to store
/// the message in.</param>
/// <param name="breakBody">Signal whether the message body should be broken into 76 char lines.</param>
/// <returns>The unique identifier (UID) of the stored message.</returns>
/// <exception cref="ArgumentNullException">The message parameter is null.</exception>
/// <exception cref="BadServerResponseException">The mail message could not be stored. The
Expand All @@ -439,7 +440,7 @@ IEnumerable<MailMessage> GetMessages(IEnumerable<uint> uids, FetchOptions option
/// the same UID.</remarks>
/// <seealso cref="StoreMessages"/>
/// <include file='Examples.xml' path='S22/Imap/ImapClient[@name="StoreMessage"]/*'/>
uint StoreMessage(MailMessage message, bool seen = false, string mailbox = null);
uint StoreMessage(MailMessage message, bool seen = false, string mailbox = null, bool breakBody = true);

/// <summary>
/// Stores the specified mail messages on the IMAP server.
Expand All @@ -451,6 +452,7 @@ IEnumerable<MailMessage> GetMessages(IEnumerable<uint> uids, FetchOptions option
/// <param name="mailbox">The mailbox the messages will be stored in. If this parameter is
/// omitted, the value of the DefaultMailbox property is used to determine the mailbox to store
/// the messages in.</param>
/// <param name="breakBody">Signal whether the message body should be broken into 76 char lines.</param>
/// <returns>An enumerable collection of unique identifiers (UID) representing the stored
/// messages on the server.</returns>
/// <exception cref="ArgumentNullException">The messages parameter is null.</exception>
Expand All @@ -467,7 +469,7 @@ IEnumerable<MailMessage> GetMessages(IEnumerable<uint> uids, FetchOptions option
/// the same UID.</remarks>
/// <seealso cref="StoreMessage"/>
IEnumerable<uint> StoreMessages(IEnumerable<MailMessage> messages, bool seen = false,
string mailbox = null);
string mailbox = null, bool breakBody = true);

/// <summary>
/// Copies the mail message with the specified UID to the specified destination mailbox.
Expand Down
11 changes: 7 additions & 4 deletions ImapClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,7 @@ public IEnumerable<MailMessage> GetMessages(IEnumerable<uint> uids, FetchOptions
/// <param name="mailbox">The mailbox the message will be stored in. If this parameter is
/// omitted, the value of the DefaultMailbox property is used to determine the mailbox to store
/// the message in.</param>
/// <param name="breakBody">Signal whether the message body should be broken into 76 char lines.</param>
/// <returns>The unique identifier (UID) of the stored message.</returns>
/// <exception cref="ArgumentNullException">The message parameter is null.</exception>
/// <exception cref="BadServerResponseException">The mail message could not be stored. The
Expand All @@ -1291,10 +1292,10 @@ public IEnumerable<MailMessage> GetMessages(IEnumerable<uint> uids, FetchOptions
/// the same UID.</remarks>
/// <seealso cref="StoreMessages"/>
/// <include file='Examples.xml' path='S22/Imap/ImapClient[@name="StoreMessage"]/*'/>
public uint StoreMessage(MailMessage message, bool seen = false, string mailbox = null) {
public uint StoreMessage(MailMessage message, bool seen = false, string mailbox = null, bool breakBody = true) {
AssertValid();
message.ThrowIfNull("message");
string mime822 = message.ToMIME822();
string mime822 = message.ToMIME822(breakBody);
lock (sequenceLock) {
PauseIdling();
if (mailbox == null)
Expand Down Expand Up @@ -1327,6 +1328,7 @@ public uint StoreMessage(MailMessage message, bool seen = false, string mailbox
/// <param name="mailbox">The mailbox the messages will be stored in. If this parameter is
/// omitted, the value of the DefaultMailbox property is used to determine the mailbox to store
/// the messages in.</param>
/// <param name="breakBody">Signal whether the message body should be broken into 76 char lines.</param>
/// <returns>An enumerable collection of unique identifiers (UID) representing the stored
/// messages on the server.</returns>
/// <exception cref="ArgumentNullException">The messages parameter is null.</exception>
Expand All @@ -1343,11 +1345,12 @@ public uint StoreMessage(MailMessage message, bool seen = false, string mailbox
/// the same UID.</remarks>
/// <seealso cref="StoreMessage"/>
public IEnumerable<uint> StoreMessages(IEnumerable<MailMessage> messages, bool seen = false,
string mailbox = null) {
string mailbox = null, bool breakBody = true)
{
messages.ThrowIfNull("messages");
List<uint> list = new List<uint>();
foreach (MailMessage m in messages)
list.Add(StoreMessage(m, seen, mailbox));
list.Add(StoreMessage(m, seen, mailbox, breakBody));
return list;
}

Expand Down
35 changes: 24 additions & 11 deletions MailMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ public static class MailMessageExtension {
/// </summary>
/// <param name="message">The MailMessage instance to construct the textual representation
/// from.</param>
/// <param name="breakBody">Signal whether the message body should be broken into 76 char lines.</param>
/// <returns>An RFC822/MIME-compliant string representing the specified mail message.</returns>
/// <exception cref="InvalidOperationException">The From property is null or has not been
/// properly initialized.</exception>
internal static string ToMIME822(this MailMessage message) {
internal static string ToMIME822(this MailMessage message, bool breakBody = true) {
NameValueCollection header = BuildHeader(message);
StringBuilder builder = new StringBuilder();

Expand All @@ -63,7 +64,7 @@ internal static string ToMIME822(this MailMessage message) {
}
// The mail body is separated by an empty line from the header.
builder.AppendLine();
builder.Append(BuildBody(message, header));
builder.Append(BuildBody(message, header, breakBody));
builder.AppendLine();

return builder.ToString();
Expand Down Expand Up @@ -208,11 +209,13 @@ static string GenerateContentBoundary() {
/// <param name="m">The MailMessage instance to build the mail body from.</param>
/// <param name="header">The RFC822/MIME mail header to use for constructing the mail
/// body.</param>
/// <param name="breakBody">Toggles the breaking of the message body lines.</param>
/// <returns>An RFC822/MIME-compliant mail body as a string.</returns>
/// <remarks>According to RFC2822 each line of a mail message should at max be 78 characters in
/// length excluding carriage return and newline characters. This method accounts for that and
/// ensures line breaks are inserted to meet this requirement.</remarks>
static string BuildBody(MailMessage m, NameValueCollection header) {
/// ensures line breaks are inserted to meet this requirement. Use breakBody set to false to disable
/// line breaking in case original message formatting has to be preserved.</remarks>
static string BuildBody(MailMessage m, NameValueCollection header, bool breakBody = true) {
StringBuilder builder = new StringBuilder();
bool multipart = header["Content-Type"].Contains("boundary");
// Just a regular RFC822 mail w/o any MIME parts.
Expand All @@ -230,7 +233,7 @@ static string BuildBody(MailMessage m, NameValueCollection header) {
builder.AppendLine("--" + boundary);
AddNestedMixed(builder, m);
} else {
AddBody(builder, m, header, true);
AddBody(builder, m, header, true, breakBody);
foreach (AlternateView v in m.AlternateViews) {
builder.AppendLine("--" + boundary);
AddAttachment(builder, v);
Expand All @@ -254,8 +257,10 @@ static string BuildBody(MailMessage m, NameValueCollection header) {
/// <param name="header">The RFC822/MIME mail header to use for constructing the mail body.</param>
/// <param name="addHeaders">Set to true to append body headers before adding the actual body
/// part content.</param>
/// <param name="breakBody">Sets whether the message body should be broken up into 76 char lines.
/// Breaking up the text may badly mess up the original formating of the message body.</param>
static void AddBody(StringBuilder builder, MailMessage m,
NameValueCollection header, bool addHeaders = false) {
NameValueCollection header, bool addHeaders = false, bool breakBody = true) {
bool base64 = header["Content-Transfer-Encoding"] == "base64";
if (addHeaders) {
string contentType = m.IsBodyHtml ? "text/html" : "text/plain";
Expand All @@ -273,11 +278,19 @@ static void AddBody(StringBuilder builder, MailMessage m,
byte[] bytes = m.BodyEncoding.GetBytes(m.Body);
body = Convert.ToBase64String(bytes);
}
StringReader reader = new StringReader(body);
char[] line = new char[76];
int read;
while ((read = reader.Read(line, 0, line.Length)) > 0)
builder.AppendLine(new string(line, 0, read));
if (breakBody)
{
StringReader reader = new StringReader(body);
char[] line = new char[76];
int read;
while ((read = reader.Read(line, 0, line.Length)) > 0)
builder.AppendLine(new string(line, 0, read));
}
else
{
builder.Append(body);
builder.AppendLine();
}
}

/// <summary>
Expand Down