SharePoint 2010
Transcription
SharePoint 2010
WCF Services in InfoPath 2010 nutzen Abstract Gerade wenn man schreibend von InfoPath aus auf eine SQL-Server Datenbank zugreifen will, kommt man quasi um einen Web Service nicht herum. In diesem Post beschreibe ich, wie man prinzipiell einen WCF Services bauen muss, damit er von InfoPath 2010 nutzbar ist. Will man Daten in InfoPath aus mehreren Datenbank Tabellen lesen bzw. auch wieder zurückschreiben, kommt man um die Erstellung eines Webservice kaum herum. Idealerweise nutzt man dafür einen WCF Service. Dieser Post zeigt an einem sehr einfachen Beispiel, wie man prinzipiell einen WCF Service bauen muss, damit man ihn in InfoPath nutzen kann. 1.1 WCF Service erstellen Ich versuche normalerweise immer klein anzufangen und möglichst das ganze Szenario zu testen, um nicht später wieder ewig lange nach fehlern zu suchen. D.h. wir gehen erst mal so vor: - Minimalen WCF Service erstellen, der einfach nur einen Wert zurückgibt WCF Service deployen In InfoPath eine Datenquelle auf den WCF hinzufügen und testen, ob das ganze funktioniert Also los geht’s. In VS2010 erstellen wir ein leeres SharePoint Projekt mit den folgenden Parametern: - Name: 1stQuad.WCFServiceTest Als Farm Solution einstellen Als nächstes brauchen wir die folgenden Referenzen: - System.ServiceModel Microsoft.SharePoint.Client.ServerRuntime (zu finden im Global Assembly Cache unter c:\windows\assembly) Unser Projekt sieht danach wie folgt aus: 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth Als nächstes brauchen wir einen „SharePoint Mapped Folder“ auf das ISAPI Verzeichnis. Rechtsklick auf den Projektordner und Add -> SharePoint Mapped Folder.Danach den ISAPI Ordner auswählen: Am Besten legt man nun noch einen Unterordner darin an, damit es im ISAPI Ordner später nicht wie Kraut und Rüben aussieht. In diesen Ordner legen wir eine Service Host Definition Datei an. Diese hat die Erweiterung .svc. In unserem Beispiel nenne ich sie contact.svc (gedacht ist noch ein weiterer 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth Post mit einer komplexeren Implementierung des WCF Service ;-) ). Das ist im Moment noch eine leere Textdatei. Unser Projekt sieht also jetzt so aus: Als nächstes erstelle ich den Servcie Contract, d.h. die Definition, wie ich auf meinen Service zugreifen will. Dies ist einfach nur eine Interface Definition. Ich nenne mein Interface IcontactService. Im Interface definiere ich momentan nur eine Methode GetContact. Für unseren ersten Test ohne Anhand von Attributen wird das Interface als ServiceContract und die Methode als OperationContract deklariert. Der Code sieht wie folgt aus: using using using using using System; System.ServiceModel; System.ServiceModel.Activation; Microsoft.SharePoint; Microsoft.SharePoint.Client.Services; namespace _1stQuad.WCFServiceTest { [ServiceContract] public interface IContactService { [OperationContract] string GetEcho(); } } Unser kleiner WCF Service soll also eine Methode haben mit Namen GetEcho(), welche einfach nur einen String zurückgibt. Wir nutzen diese Funktion, um die Funktionsfähigkeit unseres Webdienstes zu testen. Nun wird der eigentliche Service umgesetzt, der das Interface implementiert. Hierzu wird wieder eine Code Datei hinzugefügt. Die Inplementierung sieht wie folgt aus: using using using using System; System.ServiceModel.Activation; Microsoft.SharePoint; Microsoft.SharePoint.Client.Services; namespace _1stQuad.WCFServiceTest { [BasicHttpBindingServiceMetadataExchangeEndpointAttribute] [AspNetCompatibilityRequirementsAttribute(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth public class ContactService: IContactService { public string GetEcho() { return "Kontakt Service funktioniert"; } } } Wichtig an obigem Beispiel sind die Attribute bei unserer Service Klasse. Diese Attribute sorgen dafür, dass SharePoint automatisch die entsprechenden Endpunkte für den Austausch der Metadaten für unseren Service erzeugen kann. Wir brauchen also keine Konfigurationsdateien zu erstellen. Das ist natürlich sehr komfortabel. Im Falle von InfoPath sind diese Attribute zwingend notwendig, da sonst der WCF nicht erkannt bzw. konsumiert werden kann. Als nächstes müssen wir noch die .svc Datei mit der entsprechenden Processing Instruction füllen. Diese Datei wird von der WCF Services Infratsruktur benutzt, um auf eingehende Meldungen zu reagieren. Wir müssen zum Einen das Service Attribut setzen, welches die Assembly unseres Services definiert. An dieser Stelle ist wieder Reflector unser Freund (http://www.redgate.com/products/reflector/). Zum Anderen können wir eine Service Host Factory Klasse von Microsoft.SharePoint.Client.ServerRuntime nutzen, um die Endpunkte dynamisch erzeugen zu lassen. Je nachdem, ob wir einen SOAP, REST oder WCF Data Service implementieren, müssen eine der folgenden 3 Factories benutzen: • • • SOAP = MultipleBaseAddressBasicHttpBindingServiceHostFactory REST = MultipleBaseAddressWebServiceHostFactory Data Service = MultipleBaseAddressDataServiceHostFactory In unserem Fall setzen wir einen WCF Data Service um. Unsere Contact.svc Datei sieht damit wie folgt aus: <%@ServiceHost Language="C#" Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHos tFactory,Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" Service="_1stQuad.WCFServiceTest.ContactService, 1stQuad.WCFServiceTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d94370c6a68e3202" %> Der Public Key muss natürlich ggf. angepasst werden. 1.2 WCF Service verteilen und testen Jetzt ist unser minimaler Service erst mal fertig und kann deploeyd werden (Rechtklick auf das Projekt und Auswahl von Deploy). Zum Test kann man im ISAPI Verzeichnis (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\1stQuad.WCFServiceTest) 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth nachsehen, ob alles geklappt hat. Zusätzlich kann man im GAC (c:\windows\assembly) nachsehen, ob die Assembly für unseren WCF Service verteilt wurde. Jetzt kann man ihn zum Test im Browser aufrufen. Das geht mit folgender URL: http://<website-url>/_vti_bin/1stQuad.WCFServiceTest/Contact.svc/MEX Wichtig ist der Zusatz /MEX, da unser Service ein Metadata Exchange Endpunkt benutzt. Dafür konnten wir uns eben die web.config Datei für unserem Service sparen. Im Browser wird nun die WSDL datei angezeigt: 1.3 WCF Service in InfoPath nutzen Da unser WCF Service nun anscheinend funktioniert (zumindest läßt sich die WSDL Datei abfufen), sollten wir diesen als nächstes in InfoPath nutzen. Wir machen also InfoPath 2010 auf und erstellen ein neues leeres Formular. Als nächstes fügen wir eine neue Datenquelle hinzu, von der wir Daten empfangen wollen: Im nächsten schritt wählen wir einen SOAP Webservice aus: 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth Danach müssen wir die URL auf unseren WCF Service eintragen (siehe oben). Wie gesagt am Ende das MEX nicht vergessen, da der Service sonst nicht gefunden wird: Dadurch müsste InfoPath 2010 die Methoden des WCF Service bereits automatisch ermitteln können. Schliesslich kann InfoPath ja nun die WSDL Datei abrufen: Im nächsten Schritt können wir noch sagen, ob die Daten auch offline nutzen wollen. Das sparen wir uns in unserem Fall: Im letzten Schritt setzen wir die Option „Automatically retrieve Data when form is opened“, da wir die Daten gleich nach dem Start des Formulars in einer Textbox darstellen wollen: 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth Dann können wir auf Finish drücken und unsere Datenquelle ist bereit für die Nutzung. Wir brauchen jetzt noch eine Textbox, in dem der Rückgabewert aus dem WCF Service angezeigt werden soll: In den Eigenschaften der Textbox selektieren wir den Default Value: Und wählen dann das Funktionssymbol aus, um unsere Datenquelle auszuwählen: Im folgenden Dialog klicken wir auf „Insert Field or Group…“, da wir ein Feld aus unserer externen Datenquelle, die wir zuvor erstellt haben, einfügen wollen. 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth Im Dialog für die Datenquellen, selektieren wir unseren Rückgabewert aus dem WCF Service: Jetzt noch 3-mal OK klicken und unser Formular ist fertig. Testen kann man nun das Formular, indem man das Preview Icon in der Quick Access Toolbar anklickt: Danach sollten wir die Echo Meldung des WCF Service in der Textbox des geöffneten Formulars sehen: Zugegebener Maßen war dies jetzt noch keine Raketentechnik, aber oft sind es gerade die kleinen Dinge, die einem zur Verzweiflung bringen können. 1stQuad Solutions GmbH Sonnenbergstrasse 32 CH-8603 Schwerzenbach 1stQuad Solutions GmbH Tiroler Ring 55 D-86609 Donauwörth