2016-03-15 1 views
0

J'ai un fournisseur de messagerie qui utilise SMTP et IMAP de Mailkit. La fonction principale que j'utilise actuellement est de lire les messages de la boîte de réception, et selon le contenu de l'e-mail, ils vont dans un dossier «traité» ou «ignoré». Dans les systèmes existants que nous avons utilisés avec Exchange, ces dossiers existent en tant que sous-dossiers de la boîte de réception. Si les dossiers n'existent pas, ils sont créés. Un extrait de code exemple est ci-dessous:Création de dossiers GMail avec Mailkit

 var _inboxFolder = _provider.GetInboxFolder(); 
     var folder = _inboxFolder.GetChildFolder(folderName); 
     if (folder == null) 
     { 
      // If Gmail, Inbox does not allow children. Check for folder in root. 
      folder = _provider.GetFolder(folderName); 
     } 
     if (folder == null) 
     { 
      // Create new folder under Inbox 
      folder = _inboxFolder.CreateChildFolder(folderName); 
      if (folder == null) 
      { 
       // Cannot create under Inbox, create on root 
       folder = _provider.CreateFolderOnRoot(folderName); 
      } 
     } 

Ces tous utiliser mon propre fournisseur qui est basé sur une interface que nous utilisons pour d'autres fournisseurs, donc il y a une certaine logique « étrange » là-bas qui est logique pour les autres fournisseurs. GetInboxFolder et GetFolder retournent un dossier, mais retourne null si on ne peut pas le trouver. Cela fonctionne très bien dans tous les fournisseurs - si les dossiers n'existent pas, ils peuvent être créés.

Le problème survient lors de la création des dossiers. Si les dossiers ne peuvent pas être trouvés, ils doivent être créés dans le dossier Boîte de réception. Si cela ne peut pas arriver (comme dans Gmail), il devrait les créer dans le dossier racine. Cependant, tenter de créer un dossier sous le dossier Boîte de réception n'échoue pas, il crée simplement une étiquette appelée "INBOX/FolderName". Idéalement, je voudrais avoir une tentative de créer ce dossier échouer afin qu'il puisse simplement être créé à la racine. J'imagine que c'est un problème dans la conversion d'IMAP au système d'étiquette GMail.

Y at-il un moyen d'empêcher le libellé "INBOX/FolderName", ou d'identifier ce problème avant de le créer? Ou existe-t-il un moyen d'identifier qu'il s'agit d'un serveur gmail et de mettre en place une clause spéciale pour cela?

Pour un peu plus d'informations, le code CreateChildFolder et CreateFolderOnRoot est ci-dessous.

IMAPFolder Classe

public IEmailFolder CreateChildFolder(string displayName) 
    { 
     if (_imapClient == null || !_imapClient.IsConnected) 
     { 
      throw new NotLoggedInException(); 
     } 

     return new ImapFolder(_folder.Create(displayName, true), _imapClient); 
    } 

IMAPClient Classe

public IEmailFolder CreateFolderOnRoot(string displayName) 
    { 
     if (_client == null) 
     { 
      throw new NotLoggedInException(); 
     } 

     try 
     { 
      var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]); 
      var mailkit = toplevel.Create(displayName, true); 
      return new ImapFolder(mailkit, _client); 
     } 
     catch (Exception exception) 
     { 
      throw new LoadFolderFailedException(exception); 
     } 
    } 

Répondre

1

Le GMail "Label System" comment GMail implémente des dossiers. Ils n'implémentent pas les dossiers physiques, ce qu'ils font, ce sont des dossiers "virtuels" qui sont juste les étiquettes que l'utilisateur a définies et le dossier est juste une requête de tous les messages auxquels cette étiquette est appliquée. Cela signifie que l'espace de noms racine GMail est string.Empty. Certains serveurs IMAP ont un espace de noms racine de "INBOX" (comme Courier IMAP, je pense).

Votre méthode CreateFolderOnRoot devrait créer un dossier à la racine pour GMail, il ne le créera pas sous INBOX, donc votre question est très confuse.

Si vous voulez ajouter le dossier sous le INBOX, il suffit d'utiliser client.Inbox.Create (displayName, true);

Le problème arrive lors de la création des dossiers. Si les dossiers ne peuvent pas être trouvés, ils doivent être créés dans le dossier Boîte de réception.

Cela me fait penser que ce que vous voulez vraiment faire est la suivante:

try { 
    var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]); 
    var mailkit = folder.GetSubfolder(displayName); 
    return new ImapFolder(mailkit, _client); 
} catch (Exception ex) { 
    throw new LoadFolderFailedException(ex); 
} 

Notez l'utilisation de GetSubfolder par opposition à Create. Create va toujours créer le dossier. GetSubfolder ne l'obtiendra que si elle existe.

+0

Identifier que le dossier n'existe pas n'est pas un problème, le seul problème est sur la création du dossier. La logique que je veux est: - Obtenez le dossier sous le dossier de boîte de réception. - Si ce n'est pas le cas, récupérez le dossier à partir de la racine. - Si ce n'est pas le cas, créez le dossier sous le dossier de la boîte de réception. - Si cela ne peut pas être fait, créez-le à la racine. Le problème est lorsque vous tentez de créer le dossier sous la boîte de réception. Avec une structure de dossier authentique, cela fonctionne, mais avec gmail, il crée un dossier "INBOX/Label", au lieu d'échouer. –

+0

Oh, eh bien, la seule solution à ce problème, alors, est d'avoir une logique GMail-spécifique dans votre code pour gérer ce cas. – jstedfast