MailSystem.Net删除消息,IndexOnServer属性= 0

时间:2012-10-31 14:20:57

标签: c# imap

我正在使用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 个答案:

答案 0 :(得分:5)

您可以尝试通过 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);
}

答案 1 :(得分: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;
                }
            }
        }
    }

答案 2 :(得分:0)

只需在邮件索引中添加1即可。

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

答案 3 :(得分:0)

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

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

相关问题