MailSystem.Net Delete Message, IndexOnServer Property = 0
Asked Answered
B

4

6

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.

Bethina answered 31/10, 2012 at 14:20 Comment(0)
C
5

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);
}
Carmelinacarmelita answered 4/11, 2012 at 22:47 Comment(6)
Just to point out, even though this method deletes by the UID, it is still reliant on the loop counter/MessageCount, so it would pose the same issue as described in my (edited) OP.Bethina
This does not use the SearchParse method, but does its own filtering so you would not run into that issue. I wrote my own email class which is like the Message class but contains the UID. This way I can retreive and filter messages, but they can always be deleted, copied, or moved by their unique id.Carmelinacarmelita
So basically you're suggesting I loop through all the messages in the inbox so I don't have an issue. I'll see if this can work for me, but the reason this wasn't my first method of choice was because there can potentially be thousands of emails, and looping through all would negatively impact performance (as is, without it being an asynchronous task or the like).Bethina
I'm testing this one out and am running into an issue where after I delete the email, the counter increments one, so the index is now 2. The problem is now that the first message was deleted, there is no 2, only 1. So it's giving invalid messageset again. How do I get around this?Bethina
I've updated my first example to account for the index shifting up after a message is deleted. The second example shouldn't be affected by that however since it retreives all messages before deleting.Carmelinacarmelita
Thanks for your help. Will award you in 4 hours.Bethina
D
1

This is official example from documantation. instead of inbox.search("all") change it to your search query, etc.

http://mailsystem.codeplex.com/discussions/269304

    //action_id is the Message.MessageId of the email
    //action_flag is the Gmail special folder to move to (Trash)
    //copying to Trash removes the email from the inbox, but it can't be moved back once done, even from the web interface
    public static void move_msg_to(string action_id, string action_flag)
    {
        Imap4Client imap = new Imap4Client();
        imap.ConnectSsl("imap.gmail.com", 993);
        imap.Login("[email protected]", "heythatsmypassword");

        imap.Command("capability");

        Mailbox inbox = imap.SelectMailbox("inbox");
        int[] ids = inbox.Search("ALL");
        if (ids.Length > 0)
        {
            Message msg = null;
            for (var i = 0; i < ids.Length; i++)
            {
                msg = inbox.Fetch.MessageObject(ids[i]);
                if (msg.MessageId == action_id)
                {
                    imap.Command("copy " + ids[i].ToString() + " [Gmail]/" + action_flag);
                    break;
                }
            }
        }
    }
Deutschland answered 4/11, 2012 at 22:29 Comment(0)
S
0

just add 1 to the message index.

   foreach (Message newMessage in messages)
{
    inbox.DeleteMessage(newMessage.IndexOnServer + 1, true);
}
Savoirfaire answered 20/1, 2014 at 4:27 Comment(0)
K
0

Try deleting last message first then second last and then come to delete first message.

IF you delete and expunge have been set then message number changes.

Kistner answered 13/6, 2015 at 7:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.