Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MailSystem.Net Delete Message, IndexOnServer Property = 0

Tags:

c#

imap

I'm using MailSystem.NET and trying to delete a message from the server. The problem is the IndexOnServer property is 0, and I get the following error:

Command "store 0 +flags.silent (\Deleted)" failed : 121031084812790 BAD Error in IMAP command STORE: Invalid messageset

Here's my code:

    Imap4Client client = new Imap4Client();
    client.Connect(account.Server, account.Username, account.Password);
    var inbox = client.SelectMailbox("Inbox");
    MessageCollection messages = inbox.SearchParse("SINCE " + DateTime.Now.AddHours(-hours).ToString("dd-MMM-yyyy"));

    foreach (Message newMessage in messages)
    {
        inbox.DeleteMessage(newMessage.IndexOnServer, true);
    }

How do I get the correct index of the message so I can delete it?


Edit:

The problem with the suggestions using the standard 1-based loop is that the counter index won't be in sync with the message index, since in my case I'm searching to retrieve a specific subset of messages only (as I understand it).

Thank you.

like image 432
Rivka Avatar asked Oct 31 '12 14:10

Rivka


1 Answers

You can try deleting by the UID which should be more reliable and unique to each message. This has worked well for me in the past.

Edit: Since deleting the message causes all the indexes to shift down by one, you can use two separate counters. One to keep track of when you have iterated through the entire box (messagesLeft) and the other will keep track of the current message index which will be decreased by 1 if a message is deleted (since it would move up one place in line).

Mailbox box = client.AllMailboxes["inbox"];
Fetch fetch = box.Fetch;
int messagesLeft = box.Count;
int msgIndex = 0;

while (messagesLeft > 0)
{
    msgIndex++;
    messagesLeft--;
    Message email = fetch.MessageObject(msgIndex);

    if (criteria)
    {
        box.UidDeleteMessage(fetch.Uid(msgIndex), true);
        msgIndex--;
    }
}

In response to your comment, here is a fuller example of how you can use the UID for deletion without being concerned with the numeric position / index.

class Email
{
       int UID { get; set; }
       DateTime Sent { get; set; }
       public string Body { get; set; }
       // put whichever properties you will need
}

List<Email> GetEmails(string mailbox);
{
    Mailbox box = client.AllMailboxes[mailbox];
    Fetch fetch = box.Fetch;

    List<Email> list = new List<Email>();
    for (int x = 1; x <= box.MessageCount; x++)
    {
        Message msg = fetch.MessageObject(x);
        list.Add(new Email() { } // set properties from the msg object
    }

    return list;
}

void DeleteEmail(Email email, string mailbox)
{
       Mailbox box = client.AllMailboxes[mailbox];
       box.UidDeleteMessage(email.Uid, true);
}

static void Main()
{
    List<Email> emails = GetEmails("inbox");
    emails = emails.Where(email => email.Sent < DateTime.Now.AddHours(-hours))
    foreach (Email email in emails)
         DeleteEmail(email);
}
like image 81
Despertar Avatar answered Oct 21 '22 13:10

Despertar