Sonntag, Januar 20, 2008

Exchange 2007 Webservice Zugriff mit VS 2008

Ich hab mich am Wochenende mit Exchange 2007 WebService Zugriff beschäftigt. Ich habe dazu auch einige nette Guides gefunden im Internet, unter anderem von Eric Lee. Meine Versuche gestalteten sich allerdings etwas schwieriger. Ich wollte alles mit Visual Studio 2008 machen, allerdings basiert hier alles auf WCF. Die generierten Proxy-Klassen sich komplett anders aus, so dass die Beschreibungen nicht ganz halfen.

Zu erst musste ich mal meine Konfigurationsdatei hinbiegen, irgendwann sah die Datei so aus:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
      <client>
        <endpoint name="CapeVisionExchange" address="https://mail.capevision.net/EWS/Exchange.asmx" binding="basicHttpBinding" bindingConfiguration="ExchangeServiceBinding" contract="ExchangeWebServices.ExchangeServicePortType" behaviorConfiguration="ServiceAuth">
        </endpoint>
      </client>
      <behaviors>
        <endpointBehaviors>
          <behavior name="ServiceAuth">
            <clientCredentials >
              <windows allowNtlm="true" allowedImpersonationLevel="Identification"/>
            </clientCredentials>
          </behavior>
        </endpointBehaviors>
      </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="ExchangeServiceBinding" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="Transport">
                      <transport clientCredentialType="Ntlm" proxyCredentialType="None" />
                      <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
    </system.serviceModel>

</configuration>

Das war nicht mehr mit den alten WebService-Kenntnissen vergleichbar, allerdings es funktioniert.

Ich habe anschließend versucht mich nahe an dem Beispiel entlang zu hangeln, aber irgendwie war alles anders. Letztendlich habe ich es geschafft und einen Aufruf hinbekommen.  ExpandDL ist zur Abfrage von Distribution Lists (Verteiler) gedacht, eine komplette Dokumentation der WebServices gibt es in der MSDN. Nun aber mein Code-Brocken.
ExpandDLType dl = new ExpandDLType();
EmailAddressType addr = new EmailAddressType();
addr.EmailAddress = "<email>@capevision.de";
dl.Mailbox = addr;
ExchangeServicePortTypeClient exchange = new ExchangeServicePortTypeClient();
exchange.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
ExpandDLResponseType resp;
exchange.ExpandDL(null, null, "de-DE", null, dl, out resp);

Die Rückgabe der Methode enthält den Response und auch alle Nutzer der Liste. Aber am besten mal selber ausprobieren.

Mein zweiter Versuch zielte dann auf die Suche nach bestimmten Mail-Items, allerdings bin ich hier noch nicht glücklich. Ich habe 20 Zeilen Code (eine Übertreibung) und noch immer keine Ergebnisse. Am leichtesten hat sich die Entwicklung mit dem durchstöbern der Proxy-Klasse gemacht und immer wieder probieren. Fehlermeldung lesen, meist wird die Basisklasse genannt, anschließend in der Proxy-Klasse suchen und dann versuchen weiterzukommen. Meist beginnt der Prozess wieder von vorn. Nicht desto trotz hier mal der Code bisher: (bekomme keine Ergebnisse)
FindItemType item = new FindItemType();
item.Traversal = ItemQueryTraversalType.Shallow;
item.ItemShape = new ItemResponseShapeType();
item.ItemShape.BaseShape = new DefaultShapeNamesType();
item.ItemShape.BodyTypeSpecified = true;
item.ItemShape.BaseShape = DefaultShapeNamesType.Default;
GroupByType g = new GroupByType();
g.Order = SortDirectionType.Ascending;
item.Item1 = g;
PathToUnindexedFieldType u = new PathToUnindexedFieldType();
u.FieldURI = UnindexedFieldURIType.itemParentFolderId;
g.Item = u;
g.AggregateOn = new AggregateOnType();
g.AggregateOn.Aggregate = AggregateType.Minimum;
g.AggregateOn.Item = u;
item.Restriction = new RestrictionType();
ContainsExpressionType c = new ContainsExpressionType();
c.ContainmentMode = ContainmentModeType.Substring;
c.ContainmentComparison = ContainmentComparisonType.IgnoreCase;
PathToUnindexedFieldType pi = new PathToUnindexedFieldType();
pi.FieldURI = UnindexedFieldURIType.itemSubject;
c.Item = pi;
c.Constant = new ConstantValueType();
c.Constant.Value = "Test";
item.Restriction.Item = c;
IndexedPageViewType i = new IndexedPageViewType();
i.Offset = 0;
i.MaxEntriesReturned = 10;
item.Item = i;
DistinguishedFolderIdType id = new DistinguishedFolderIdType();
id.Id = DistinguishedFolderIdNameType.inbox;
item.ParentFolderIds = new BaseFolderIdType[] { id };
item.SortOrder = new FieldOrderType[1];
item.SortOrder[0] = new FieldOrderType();
item.SortOrder[0].Order = SortDirectionType.Ascending;
item.SortOrder[0].Item = pi;
ExpandDLType dl = new ExpandDLType();
EmailAddressType addr = new EmailAddressType();
addr.EmailAddress = "<email>@capevision.de";
dl.Mailbox = addr;
ExchangeServicePortTypeClient exchange = new ExchangeServicePortTypeClient();
exchange.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
FindItemResponseType findResp;
exchange.FindItem(null, null, Thread.CurrentThread.CurrentUICulture.ToString(), null, item, out findResp);
Console.WriteLine(resp.ToString());

3 Kommentare:

Anonym hat gesagt…

Hallo Jan,
bin beim "problemlösen" über deine Erfahrung mit dem Webservice gestolpert.
Versuche mich auch gerade an dem Teil und du schreibst irgendwo das du keine Daten zurück bekommst.
Ich habe ein änliches Problem, d.h. eigentlich funktioniert alles soweit aber wenn ich versuche mit 'restriction' eine filter zu setzen (Datumsfileter 'grösser als 01.01.2008') bekomme ich nichts zuück. Ich erhalte sogar einen 'Objektverweis...' Fehler. Es müssten aber Daten kommen da garantiert was da ist!!
Hast du ähnliches beobachtet oder funktioiert mitlerweile bei dir alles korrekt??

Roland

Jan Zieschang hat gesagt…

Hallo Roland,
ich habe lange gekämpft mit den ganzen Filtern. Leider ist die Doku wirklich nicht sehr hilfreich für die Exchange-Zugriffe.
Ich bin bisher nicht mehr weiter zu dem Thema gekommen. Gibt leider zu viele Baustellen. Aber das Thema drückt im nächsten Monat wieder mehr. Eventuell fehlt ein Type, der zusätzlich zum Datumsfilter benötigt wird. Alternativ würde ich mal den Ordner- oder Feldnamen checken, evtl. ist hier ein Fehler. Wenn ich mich wieder intensiv mit dem Thema beschäftigt habe und die Implementierung bei mir funktioniert, dann werde ich den Code (solange es möglich ist) online stellen.

Jan Zieschang hat gesagt…

Hallo Roland, ich habe mich mal wieder mit Exchange beschäftigt. Ich habe auch mit einem Zeitstempel gearbeitet, vielleicht hilft dir das weiter.
Exchange 2007 Webservice Zugriff, GetItem macht ärger!