Share via


Integration von Dynamics CRM 4.0 in MS Office InfoPath 2007 – Teil 4 InfoPath Datenquellen und Eventhandling

Zurück in unserem InfoPath Formular gilt es nun, unsere Felder mit Daten zu befüllen. Das können wir machen, indem wir zuerst unserem Form die in Teil 3 angelegten WebService Methoden mitgeben. Unter dem Menüpunkt „View“ finden wir „DataSources“, die uns sogleich rechts angezeigt werden. Wir sehen, dass alle Felder als primäre Datenquellen angelegt wurden. Hinter dem Link „Datenquellen verwalten“ können wir neue Datenquellen hinzufügen, was wir nun exemplarisch für unsere GetAccounts WebService Methode machen werden:

Datenquellen hinzufügen

Unter der Ansicht Datenquellen wählen wir „Datenverbindungen verwalten“. Hier sehen wir alle bestehenden (derzeit noch leer) und können neue hinzufügen. Wir wollen nun 1. eine neue hinzufügen und aus dieser 2. Daten empfangen.

screen_datenquelle

Im nächsten Schritt definieren wir die Quelle, in unserem Fall soll uns ein Webdienst die Daten liefern. Als nächstes geben wir dann an, wo denn der WebService zu finden ist. Wo? Genau: das war https://localhost/VerzeichnisName/Service.asmx. Wenn wir das Formular auch außerhalb des Kontextes unseres Servers verwenden wollen, geben wir statt localhost die IP des Servers oder den Hostnamen ein.

Screen_webservice_datenquelle

Wenn alles klappt und der WebService läuft, brauchen wir danach nur die entsprechende Methode auswählen – in unserem Fall … genau: RetrieveProjects! Um weitere Informationen wie z.B. Rückgabewerte zu erfahren, müssen wir im nächsten Schritt Beispieldaten für die einzelnen Parameter angeben. Für unsere RetrieveProjects Methode ist das eine Guid für einen Account, der auch Projekte hat bzw. die Guid eines gültigen Benutzers. Hier bitte darauf achten, dass der Benutzer auch über die entsprechenden Rechte an der Entität Projekt verfügt. Werte erhalten wir am einfachsten direkt von unserem SQL-Server, dessen Management Studio sich hier als hilfreich erweist :)

screen_Beispieldaten_Datenquelle

 

Der nächste Dialog im Datasource-Wizard ist fast identisch, wir ignorieren ihn im Moment geflissentlich, da wir keine anderen Guids  als die soeben angegebenen mitschicken wollen.

Im nächsten Schritt wollen wir auch keine Kopie der Daten in der Formular speichern, wobei hier grundsätzlich zu bedenken ist, dass jeder WebService-Ruf natürlich relativ kostspielig ist. In einer Produktivumgebung, in der wesentlich mehr Daten als hier im Sandkasten zurückkommen, ist sicher eine effizientere Struktur der Datenquellen zu überlegen.

Zuletzt müssen wir noch angeben, ob wir die Daten automatisch beim Öffnen des Formulars abrufen wollen. Im Falle unserer Projektdaten wollen wir das aber nicht, da ja zuerst ein Account aus der Dropdown ausgewählt werden soll! Die Checkbox wird daher auch abgehakt (De facto werden wir das auch für die anderen Datenquellen so machen, da wir jedes Mal vorher ein bisschen was abfragen wollen, bevor wir die Abfrage dann händisch starten).

Ein Klick auf „Fertig stellen“ fügt die Datenquelle schließlich auch der Liste hinzu. Wann immer wir sie ändern wollen, werden wir hierher zurückkehren.

Dasselbe machen wir im Folgenden auch für alle anderen Datenquellen, also für RetrieveAccounts, GetProjectOwner, GetUser und schließlich unsere CrmSubmit-Methode. An diese wollen wir jedoch Daten senden, womit der Dialog sich ein wenig anders gestaltet. Wichtig ist dabei, dass wir das gesamte Formular an die Datenquelle übermitteln, wie folgendes Bild zeigt:

screen_datenquelle_submit

Damit sind alle Datenquellen unseres Formulars angelegt, was wir jetzt tun müssen, ist, den einzelnen Feldern im Formular mitzuteilen, welchen Wert bzw. welche Werte sie aus welcher Datenquelle anzeigen sollen.

Datenquellen ansprechen

Wir kehren zum Eigenschaftsfenster der Dropdownliste für Accounts aus Teil 2 dieser Reihe zurück. Hier geben wir im Abschnitt „Listenfeldelemente“ nun bekannt, woher wir die Daten des Feldes beziehen wollen: Richtig, aus unserer sekundären (also „externen“) Datenquelle „RetrieveAccounts“. Für diese Datenquelle wollen wir als Einträge jeweils ein „Result“ anzeigen lassen, wie folgende Graphik zeigt:

screen_auswahl_eintraege

Als Wert wählen wir aus dem Result die Account-ID aus, als Anzeigename wünschen wir uns den Namen des Accounts.

Für die Dropdownliste der Projekte gehen wir gleich vor, nur, dass wir jetzt die RetrieveProjects als Datenquelle heranziehen.

Bei den Textfeldern für Benutzer-ID und Projekteigner-ID schaut’s im Prinzip gleich aus, nur, dass wir hier für das Eigenschaftsfeld „Standardwert“ uns für eine Formel entscheiden. Im Formel-Editor wählen wir aus „Feld oder Gruppe“ die entsprechende Datenquelle und klicken uns über die „dataFields“ bis runter ins „result“, wo wir die „ownerid“ im Falle des Projekteigners auswählen und bestätigen.

Die anderen Textfelder zu Projektstart und Ende sowie die Eingabefelder für unsere Spesenabrechnung verknüpfen wir nicht, da wir sie entweder im Code belegen oder sie später für Benutzereingaben zur Verfügung stehen sollen.

 

Zwischenfrage: Wie frage ich Werte aus Controls und Datenquellen in InfoPath ab bzw. wie lege ich diese fest?

Wenn wir die Controls bzw. Datenquellen hinzugefügt haben, und uns unter dem Menüpunkt „View“ den Unterpunkt „Datasources“ auswählen, zeigt uns Visual Studio statt des Solution-Explorers eine Sicht auf die verfügbaren Datenquellen für unser InfoPath Formular.

Jedes einzelne Control ist hier unter dem Titel „Primär“ angeführt. Wollen wir den ausgewählten Index von z.B. der DropDown-Liste Kundenddaten im Formular abrufen, können wir das im Code nicht einfach über z.B. AccountName.SelectedIndex machen. Da in InfoPath alles XML ist, müssen wir uns einen XPathNavigator für die Maindatasource (die enthält alle Controls) erzeugen, indem wir deren CreateNavigator() Methode aufrufen. Dann holen wir uns einen einzelnen Knoten mit diesem Navigator, indem wir der Methode SelectSingleNode den XPath des Feldes übergeben. Der schnellste Weg, den XPath eines Feldes (bzw. einer Datenquelle und deren Ein- und Ausgabewerte) zu bekommen führt uns über die Liste der Datenquellen. Hier steht die Funktion „XPath kopieren“ per rechtem Mausklick auf die jeweilige Datenquelle bzw. deren Attribute zur Verfügung.

Wenn wir dann für diesen Knoten die das Value-Attribut abrufen, haben wir auch schon dessen aktuellen Wert. Analog dazu sieht das Setzen des Übergabewertes Account-ID für unsere RetrieveProjects-WebMethode wie folgt aus:

Wir erzeugen einen Navigator für die sekundäre Datenquelle „RetrieveProjects“:

DataSource source = this.DataSources["RetrieveProjects"];

XPathNavigator xNav = source.CreateNavigator();

Dann wollen wir den Wert für Account ID festlegen (den wir ja als Eingangswert für unsere WebService-Methode RetrieveProjects brauchen):

xNav.SelectSingleNode(

"/dfs:myFields/dfs:queryFields/ns2:RetrieveProjects/ns2:accountId", NamespaceManager).SetValue(giud);

Der NamespaceManager, den wir hier übergeben, wird zur Laufzeit von InfoPath erzeugt, unter anderem dafür, den Namespace aufzulösen, in dem wir arbeiten.

 

Eventhandling

Nachdem wir nun den Controls die richtigen Datenquellen zugewiesen haben und wissen, wie man Werte aus Datenquellen ausliest bzw. setzt, können wir uns dem Eventhandling widmen.

User

Das erste, was wir wissen müssen, ist, welcher User gerade das Formular geöffnet hat. System.Security.Principal.WindowsIdentity.GetCurrent().Name; liefert uns diese Information, die wir als Eingabewert an unsere Datenquelle „GetUser“ übergeben, bevor wir die Abfrage der Datenquelle mit DataSources["GetUser"].QueryConnection.Execute(); einleiten. Damit enthält der Rückgabewert der Datenquelle die Guid des angemeldeten Windows Users, das entsprechende Textfeld, das wir an diese Datenquelle gebunden haben, zeigt deshalb auch an.

TIPP:

Hier bitte darauf achten, dass das Formular-Feld des Benutzers als Read-Only gekennzeichnet ist, da die hier angezeigte ID zur Impersonisation verwendet wird!

Accounts

Als nächstes wollen wir die Accounts abfragen, deren Datenquelle wir die User-ID zuerst noch übergeben. Sowohl Userabfrage als auch Festlegung der Accounts rufen wir in der InternalStartup()-Methode des Formulars auf.

Projekte

Danach definieren wir einen Eventhandler für den Fall, dass sich der ausgewählte Account ändert. Visual Studio unterstützt uns mit dem Anlegen und Verknüpfen des Events durch Doppelklick auf die Dropdownliste der Accounts. Wenn sich der ausgewählte Index ändert wollen wir zuerst die Account-ID auslesen (über den XPathNavigator für die Datenquelle) und diese als Eingangswert an die RetrieveProjects-Datasource übergeben. Diese fragen wir dann ganz einfach wieder ab indem wir this.DataSources["RetrieveProjects"].QueryConnection.Execute(); ausführen.

Projekteigentümer

Ändert sich das ausgewählte Projekt, wollen wir schließlich noch feststellen, wer der Projekteigentümer ist. Jetzt lesen wir die ID des Projektes aus und weisen sie dem Eingangswert der GetProjectOwner-Datenquelle zu – für deren QueryConnection wir wiederum danach die Execute-Methode aufrufen. Damit ist auch die ID des Projekteigentümers im Formular sichtbar und wir sind im Prinzip auch schon wieder fertig!

Im fünften und gleichzeitig letzten Teil unserer InfoPath Reihe werfen wir noch einen Blick auf die Submit-Methode unseres WebServices, verbinden diese mit dem InfoPath Formular und deployen unsere Formularvorlage am CRM-Server…

______________________________________________________

Alexander Brandstätter, Microsoft Consulting Services