Microsoft Exchange – EWS: FindItems et récupération d’emails

Commençons par une fonction basique qui permettra de tester l’installation et la bonne configuration de votre service : La récupération d’email.

Introduction

La récupération des emails se fait en 2 temps généralement. D’abord nous avons le FindItems qui permet de renvoyer les objets correspondants à la requête. Ensuite il est possible d’appeler une 2ème méthode pour charger des propriétés spéciales, qui ne sont pas récupérées par défaut, dans les emails préalablement récupérés.

Exemple

ItemView itemView = new ItemView(iElementNb);
 
itemView.OrderBy.Add(EmailMessageSchema.DateTimeReceived, SortDirection.Descending);
 
FindItemsResults findResults = m_service.FindItems(WellKnownFolderName.Inbox, itemView);
 
//Ici, on récupère le MIME content (qui n'est pas chargé par le simple appel à la méthode FindItems)
 
PropertySet ps = new PropertySet();
 
ps.Add(ItemSchema.MimeContent);
 
m_service.LoadPropertiesForItems(findResults, ps);

L’objet ItemView permet de spécifier le nombre d’éléments à récupérer ainsi que l’ordre dans lequel ils seront retournés

La méthode FindItems possède plusieurs prototypes :

Il est possible de spécifier le dossier de recherche via son FolderID (nous y reviendrons un peu plus loin) afin de pouvoir parcourir des dossiers autres que ceux basiques (les « WellKnownFolderName »)

Il est aussi possible d’ajouter un critère de recherche, afin de récupérer seulement les emails ayant pour envoyeur Mr X, ou ceux envoyé à une date donnée…

Exemple

Récupération de tous les emails situés dans la boite de réception contenant le motif X(appelé ici sTextPattern) dans le sujet ou dans le corps de l’email

ItemView itemView = new ItemView(iElementNb);
 
itemView.OrderBy.Add(EmailMessageSchema.DateTimeReceived, SortDirection.Descending);
 
SearchFilter.SearchFilterCollection searchFilterCollection =
 
new SearchFilter.SearchFilterCollection(LogicalOperator.Or);
 
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Body, sTextPattern));
 
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject, sTextPattern));
 
findResults = m_service.FindItems(WellKnownFolderName.Inbox, searchFilterCollection, itemView);

Mise à jour:

Seulement voila, le fait d’utiliser FindItems avec un SearchFilterCollection (ou SearchFilter) créer une indexation des résultats de recherches sur le serveur Exchange. En gros, les prochaines recherches exactement similaires seront bien plus rapides, mais l’indexation fait perdre des perfs et prends de la place sur le serveur Exchange.

Pour éviter cela, il est possible d’utiliser une autre sémantique qui est la recherche Exchange Search. Pour cela, il faut utiliser les mots clés d’Advanced Query Syntax (introduction, liste de mots clés)

Le seul exemple que je donnerai ici sera l’utilisation de la propriété System.FullText qui permet de récupérer tous les emails contenant un certain motif dans:

Le corps, le titre, le contenu des pièces jointes (test sur un .txt), le nom des pièces jointes etc

À utiliser simplement comme cela:

string sRequest = "System.FullText:" + sMotifARechercher;
findResults = m_service.FindItems(WellKnownFolderName.Inbox, sRequest, itemView);

Source additionnelle: http://msdn.microsoft.com/en-us/library/hh148195(v=EXCHG.140).aspx

Voir Chapitre suivant : Ecrire et envoyer un email avec EWS API managed

Utiliser XSLT en C# (avec XML)

Bonjour,

Ci dessous le processus pour utiliser le combo xslt xml en C#

1. Créer la classe de l’objet que vous voulez serialiser en XML.

Exemple :

[XmlRoot(ElementName = "CSuiviDetail")]
 
public class CBordereauDetail
 
{
 
[XmlElement("Array1_elems")]
 
public Array1_elem[] Array1_elems;
 
public CBordereauDetail(int Array1_elemsNumber)
 
{
 
Array1_elems = new Array1_elem[Array1_elemsNumber];
 
}
 
public CBordereauDetail()
 
{
 
}
 
}
 
[XmlRoot(ElementName = "Array1_elem")]
 
public class Array1_elem
 
{
 
[XmlAttribute("semaine")]
 
public int semaine;
 
[XmlAttribute("codeIngenieur")]
 
public string codeIngenieur;
 
[XmlElement("fonctionnalite")]
 
public string fonctionnalite;
 
[XmlAttribute("charge")]
 
public double charge;
 
[XmlElement("detail")]
 
public string detail;
 
}

2.  Créer le fichier XML:

using System.Xml;
 
using System.Xml.Serialization;
 
using System.IO;
 
//Création et initialisation de l'élément "BordereauDetail"
 
//..
TextWriter writer = new StreamWriter(xmlFilename);
XmlSerializer serializer = new XmlSerializer(typeof(CBordereauDetail));
serializer.Serialize(writer, BordereauDetail);
writer.Close();

3. Executer la règle XSLT et sauver le fichier

Attention au format, en effet si vous générez le fichier avec un StreamWriter, il se peut qu’il se produise un conflit qui pose problème (fichier généré avec l’entête utf-16 mais toujours sous la forme utf-8)

Préférez le code suivant si vous rencontrez des problèmes:

Byte[] buffer = XMLXSLfunct.ApplyXSLRule(xmlFilename, xslFilename);
 
using (System.IO.Stream s = System.IO.File.Create(outputFilename))                {
 
s.Write(buffer, 0, buffer.Length);
 
}
 
//fichier XMLXSLfunct:
 
using System.IO;
 
using System.Xml;
 
using System.Xml.Linq;
 
using System.Xml.Xsl;
 
using System.Xml.XPath;
 
using Mvp.Xml.Common.Xsl;
 
public static byte[] ApplyXSLRule(string reportXmlFilename, string xslFilename)
 
{
 
 /* ----------------- TRANSFORMATION XSL ---------------- */
 
XslCompiledTransform xslt = new XslCompiledTransform();
 
try
 
{
 
xslt.Load(xslFilename);
 
}
 
catch (Exception ex)
 
{
 
int error = 0;
 
}
 
System.Xml.XPath.XPathDocument fluxXml = new System.Xml.XPath.XPathDocument (reportXmlFilename);
 
MemoryStream ms = new MemoryStream();
 
xslt.Transform(fluxXml, null, ms);
 
Byte[] buffer = new Byte[ms.Length];
 
buffer = ms.ToArray();
 
ms.Close();
 
return buffer;
 
}

Voilà, vous avez votre fichier de sortie outputFilename, généré à partir de votre classe en C#, et parsé par un XSLT de votre choix.