WCF und Silverlight in SharePoint. Teil 1: einen eigenen WCF-Dienst entwickeln und in SharePoint bereitstellen

Ich habe gerade ein größeres Projekt, bei dem zwar SharePoint als Frontend genutzt werden soll, aber ein Großteil der für die Benutzer sichtbaren Oberfläche in Silverlight gebaut werden muß. Die Anwendung soll außerdem intensiv auf SAP zugreifen – lesend und schreibend. Viele dieser SAP-Zugriffe müssen aus Silverlight erfolgen und da Silverlight im Browser, also auf dem Client, läuft und von dort der direkte Zugriff auf SAP nicht möglich ist, mußte eine Zwischenschicht her. Was bietet sich mehr an, als eigene WCF-Dienste?

Die Verwendung von Externen Inhaltstypen für die Integration von SAP wurde verworfen, weil sehr spezielle Operationen mit den Daten notwendig sind. Das könnte man zwar alles auch dort einbauen, aber die Entwicklung wäre mindestens genauso kompliziert. Außerdem werden diese Daten nur in Silverlight und nicht in SharePoint selbst benötigt. WCF-Dienste bieten die Möglichkeit genau die notwendige Funktionalität zu implementieren – nicht mehr und nicht weniger.

Zum Zugriff auf SAP benutzen wir übrigens ERPConnect von Theobald Software.

Bei meinen ersten Tests mußte ich allerdings ziemlich schnell feststellen, daß das alles gar nicht so einfach ist, wie es (zumindest für mich) auf den ersten Blick aussah. Nach intensiver Webrecherche und sehr viel Ausprobieren habe ich jetzt aber eine funktionierende Testumgebung. Es gibt einen von außen d.h. ohne Codeänderung konfigurierbaren WCF-Dienst, der direkt in SharePoint bereitgestellt wird (und damit die Berechtigungen und die Grundkonfiguration von dort übernimmt) und es gibt eine Silverlight-Anwendung, die diesen Dienst nutzen kann. Die gesamte Lösung läßt sich in WSP-Dateien verpacken und so sauber beim Kunden bereitstellen.

Normalerweise versuche ich meine Beiträge in Deutsch zu verfassen und werde das auch hier tun. Allerdings ist meine gesamte Entwicklungsumgebung englisch und ich hatte auch noch nie eine deutsche Version von Visual Studio unter den Fingern. Screenshots und Erklärungen zu Visual Studio werden also in Englisch sein.

Da das Ganze naturgemäß etwas länger ist, werde ich es in zwei Teile aufteilen. Teil 1 (dieser Beitrag) behandelt die Entwicklung des WCF-Dienstes und dessen Bereitstellung in SharePoint. Teil 2 behandelt die Entwicklung einer SharePoint-fähigen Silverlight-Anwendung, die diesen Dienst nutzt.

Teil 1: einen eigenen WCF-Dienst entwickeln und in SharePoint bereitstellen

Die Bereitstellung eines WCF-Dienstes in WSS 3.0 bzw. MOSS 2007 war relativ kompliziert. Zum einen nutzt diese Version "nur" .NET 2.0, was Änderungen an der web.config notwendig macht und zum anderen ist die Konfiguration eines WCF-Dienstes auch ohne SharePoint relativ kompliziert. In SharePoint 2010 ist das jetzt deutlich einfacher. Zum einen weil SharePoint selbst mit .NET 3.5 und WCF-Diensten arbeitet, so daß das gesamte System bereits vorbereitet ist, und zum anderen weil man die Konfiguration des Dienstes SharePoint überlassen kann.

Eine grundlegende Anleitung zur Entwicklung und Bereitstellung eines WCF-Dienstes in SharePoint findet man hier auf MSDN. Ich habe noch ein paar Erweiterungen zur dort gezeigten Vorgehensweise gemacht. Z.B. weil ich meinem Dienst Konfigurationseinstellungen von außen mitgeben mußte.

Schritt 1: erstellen des Projekts in Visual Studio

Ich beginne immer damit, mir eine leere Projektmappe in Visual Studio anzulegen. Visual Studio legt dann alle Projekte dieser Projektmappe in Unterordnern an. Wenn man das nicht tut, dann liegt später entweder die SLN-Datei in einem Unterordner oder im Ordner eines Projektes. Eine neue, leere Projektmappe erstellt man, indem man File -> New -> Project klickt und dann diese Vorlage auswählt:

Der neuen Projektmappe fügt man jetzt ein neues, leeres SharePoint-Projekt hinzu (durch Rechtsklick im Solution Explorer und dann Add -> New Project:

Ich habe es WcfDemo genannt. Wichtig ist, daß im sich öffnenden SharePoint Customization Wizard die Option "Deploy as a farm solution" ausgewählt wird. Der Dienst läßt sich nicht als sandboxed solution bereitstellen:

Dem Projekt müssen jetzt noch mehrere Verweise hinzugefügt werden (Rechtsklick auf References und dann Add Reference): System.Runtime.Serialization und System.ServiceModel werden für WCF gebraucht. System.Web wird für das Auslesen der Einstellungen gebraucht. Man findet sie direkt im .NET-Reiter:

Zur Benutzung der von SharePoint bereitgestellten Service Factories, die den Dienst automatisch konfigurieren, ist ein weiterer Verweis auf Microsoft.SharePoint.Client.ServerRuntime notwendig. Die Datei findet sich im GAC und kann über den Browse-Reiter des Dialogs ausgewählt werden:

 

Schritt 2: implementieren des Dienstes

Zum Auslesen und Bereitstellen der Einstellungen (dazu weiter unten mehr) gibt es eine statische Klasse AppSettings:

using System;

using System.Collections.Specialized;

using System.Web.Configuration;

 

namespace WcfDemo {

  internal static class AppSettings {

 

    public static string Message {

      get { return WebConfigurationManager.AppSettings["Message"]; }

    }

 

  }

}

Wie genau ein WCF-Dienst entwickelt wird, soll hier nicht weiter erläutert werden. Im Web sollten sich dazu ausreichend Quellen finden lassen. Der Dienst soll zu Testzwecken einfach einen String aus den Einstellungen zurückgeben. Wir brauchen dazu ein Interface IDemoService und eine Klasse DemoService, deren Inhalt ich hier kommentarlos bereitstelle:

using System;

using System.Collections.Generic;

using System.Runtime.Serialization;

using System.ServiceModel;

 

namespace WcfDemo {

  [ServiceContract]

  public interface IDemoService {

 

    [OperationContract]

    string GetMessage();

 

  }

}

 

 

using System;

using System.Collections.Generic;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Activation;

using Microsoft.SharePoint.Client.Services;

 

namespace WcfDemo {

  [ServiceBehavior]

  [BasicHttpBindingServiceMetadataExchangeEndpointAttribute]

  [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

  public class DemoService : IDemoService {

 

    public string GetMessage() {

      return AppSettings.Message;

    }

 

  }

}

Schritt 3: den Dienst bereitstellen

Der Dienst soll im ISAPI-Ordner unterhalb des 14-Hive bereitgestellt werden, damit er später über das von SharePoint bereitgestellte virtuelle Verzeichnis _vti_bin erreicht werden kann. Im Web finden sich mehrere Anleitungen, wie man einen WCF-Dienst konfigurierbar machen kann. Meist wird dabei entweder die web.config-Datei im ISAPI-Ordner angepaßt (eine zu SharePoint gehörende Datei, die man nicht verändern sollte) oder es wird ein eigener Service Host entwickelt, der Einstellungen dann aus einer beliebigen Quelle (Datei, Datenbank, …) verarbeiten kann (was relativ kompliziert ist).

Ich habe hier einen anderen, einfacheren Weg gewählt: wir legen den Dienst in einen Unterordner, damit wir ihm seine eigene web.config-Datei bequem per WSP-Datei mitgeben können. Diese web.config wird nichts anderes enthalten, als die benötigten Einstellungen. Wie bei ASP.NET üblich, werden dadurch alle anderen Konfigurationseinstellungen von der übergeordneten web.config (im ISAPI-Ordner) geerbt.

Wir nehmen in unser Projekt also einen "SharePoint Mapped Folder" auf (Rechtsklick auf das Projekt -> Add -> SharePoint Mapped Folder):

Dem Ordner fügen wir jetzt einen Unterordner hinzu (Rechtsklick -> Add -> New Folder), z.B. WcfDemo. In diesen Ordner nehmen wir zwei neue Dateien auf (Rechtsklick -> Add -> New Item). Als Vorlage nimmt man Text File und benennt die Dateien web.config und DemoService.svc.

Die Datei web.config enthält nur die Einstellungen, die wir im Dienst brauchen und die später jederzeit geändert werden können, z.B. wenn sich in der Umgebung beim Kunden etwas ändert. Das können z.B. Servernamen von Fremdsystemen oder Verbindungsstrings zu Datenbanken sein. Die Datei sieht so aus:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<configuration>

  <appSettings>

    <add key="Message" value="Hallo Welt!"/>

  </appSettings>

</configuration>

Durch Hinzufügen von weiteren add-Elementen kann man beliebige weitere Einstellungen ablegen und später bequem über die AppSettings-Klasse (s.o.) wieder auslesen.

Die Datei DemoService.svc stellt den eigentlichen Dienst bereit. Sie sieht so aus:

<%@ServiceHost Language="C#" Debug="true"

Service="WcfDemo.DemoService, $SharePoint.Project.AssemblyFullName$"

Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Das Factory-Attribut legt fest, wie SharePoint den Dienst konfiguriert. Die Möglichkeiten sind hier auf MSDN beschrieben. Beim Service-Attribut gibt man die Klasse mit Namensraum des Dienstes und den "fully qualified assembly name" an. Mit Visual Studio 2010 und seinen SharePoint-Projektvorlagen kann man die korrekte Angabe Visual Studio überlassen. Das Token $SharePoint.Project.AssemblyFullName$ wird nach dem kompilieren automatisch ersetzt. Was damit alles machbar ist, findet man hier auf MSDN.

Allerdings ersetzt Visual Studio standardmäßig keine Tokens in svc-Dateien. Damit das funktioniert, muß man entweder die Projektdatei editieren (dann funktioniert es in diesem Projekt) oder man paßt gleich die verantwortliche MSBuild-Datei an, damit es für alle Projekte funktioniert. Eine kurze Anleitung wie das geht findet man z.B. hier bei Andrew Connell.

Schritt 4: Abschluß und Test

Das gesamte Projekt sieht im Solution Explorer jetzt so aus:

Durch einen Rechtsklick auf das Projekt und Deploy kann es jetzt einfach kompiliert und in SharePoint bereitgestellt werden. Man kann den Dienst dann mit dem Browser über die folgende URL aufrufen: http://<sharepoint>/_vti_bin/WcfDemo/DemoService.svc/MEX (das angehängte /MEX steht für Metadata Exchange).

6 Gedanken zu “WCF und Silverlight in SharePoint. Teil 1: einen eigenen WCF-Dienst entwickeln und in SharePoint bereitstellen

  1. Hallo Andi,

    kleiner Tipp: nutze mal die Productivity Power Tools for VS 2010.

    Hier ein Blog mit den Features: http://weblogs.asp.net/scottgu/archive/2010/07/19/vs-2010-productivity-power-tools-update-with-some-cool-new-features.aspx

    Was wirklich toll zum bloggen mit dem LiveWriter oder direkt im RichText Web Editor ist der Html Output. Beim LiveWriter muss man aber über „Inhalt Einfügen“ den Html Code aus VS2010 einfügen.

    Das mit dem Unterordner würde ich auch immer so empfehlen, da dies die bestmögliche Anpassung für den Service ermöglicht.

    Also weiter so 😉

    Gefällt mir

  2. Hallo Andi!
    Deine Anleitung ist Kurz und Ausführlich! Ich habe auf dem änlichen Weg einen benutzerdefinierten Dienst erstellt. Der Test im Browser (mit angehängtem MEX) verlief zufriedenstellend. Doch wie lassen sich die einzelnen Methoden über den Browser aufrufen? Z.B. http://myServer/_vti_bin/Service1.svc/HelloWorld so funktioniert es bei mir nicht. Sorry, bin in der Sache ein Anfäger!
    Vielen Dank im vorraus!
    mfg
    Wolfgang

    Gefällt mir

  3. Hallo Wolfgang,
    das hängt letztlich von der Implementierung des Dienstes ab. In jedem Fall kann man mit dem Browser nur einen GET-Request erzeugen und Dein Dienst muß auf diesen reagieren.

    Andi

    Gefällt mir

  4. Buenos dedas, hhariri, en prmeir lugar enhorabuena por el libro. Debe ser muy sacrificado hacer un libro y lograr que lo publiquen.Viendo que puedo contactar con su autor, quisiera aprovechar a hacerte alguna consulta antes de comprarlo.He de realizar un proyecto en .net en el que he de crear un subscriptor y publicador para estar en contacto con subscriptores y publicadores hechos en java desde un cliente de mi empresa.Aunque hable de subscriptores no quiere decir que entienda bien todo esto contexto. Apenas se nada. Y se que me enviare1n informacif3n en xml y creo que ire1 dentro de un payload o algo ased. Y nosotros deberemos ir dando respuestas a la parte del cliente.Tendre9 que crear una especie de colas de mensajes por si hay problemas en las comunicaciones, que se envien en cuanto se pueda. Y la informacif3n que me mandan registrarla en una bbdd. Y tener un registro.Si sobre este tipo de cosas trata el libro y es fe1cil de entender e implantar con mucho gusto comprare9 tu libro. Me siento muy perdido y me urge muchedsimo ponerme al deda con esto.Mis conocimientos tan solo son de crear algfan servicio web en .asmx y poco me1s.Un saludo

    Gefällt mir

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s