6

我正在使用MailSystem.NET并尝试从服务器中删除一条消息。问题是 IndexOnServer 属性为 0,我收到以下错误:

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

这是我的代码:

    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);
    }

如何获取消息的正确索引以便删除它?


编辑:

使用基于 1 的标准循环的建议的问题是计数器索引不会与消息索引同步,因为在我的情况下,我正在搜索仅检索特定的消息子集(据我了解) .

谢谢你。

4

4 回答 4

5

您可以尝试按 UID 进行删除,该UID对于每条消息应该更可靠和唯一。这在过去对我来说效果很好。

编辑:由于删除消息会导致所有索引向下移动一个,因此您可以使用两个单独的计数器。一个用于跟踪您何时遍历整个框(messagesLeft),另一个将跟踪当前消息索引,如果删除一条消息,该索引将减 1(因为它会在一行中向上移动一个位置)。

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--;
    }
}

为了回应您的评论,这里有一个更完整的示例,说明如何使用 UID 进行删除而不关心数字位置/索引。

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);
}
于 2012-11-04T22:47:21.833 回答
0

这是来自文档的官方示例。而不是 inbox.search("all") 将其更改为您的搜索查询等。

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("heythatsme@gmail.com", "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;
                }
            }
        }
    }
于 2012-11-04T22:29:07.997 回答
0

只需将 1 添加到消息索引。

   foreach (Message newMessage in messages)
{
    inbox.DeleteMessage(newMessage.IndexOnServer + 1, true);
}
于 2014-01-20T04:27:35.523 回答
0

尝试先删除最后一条消息,然后删除倒数第二条,然后再删除第一条消息。

如果您已设置删除和删除,则消息编号会更改。

于 2015-06-13T07:22:57.783 回答