Toolkit für die Integration von Forderungen, Azure und SharePoint - Teil 5

Toolkit für die Integration von Forderungen, Azure und SharePoint - Teil 5

Dies ist Teil 5 einer fünfteiligen Serie zum CASI Kit (Claims, Azure and SharePoint Integration, Integration von Forderungen, Azure und SharePoint). Teil 1 ist eine einführende Übersicht über das gesamte Framework und die Lösung. Es wird erläutert, welche Themen in der Serie behandelt und abgedeckt werden. Teil 2 enthält Anweisungen zum Erstellen von WCF-Anwendungen und zum Festlegen der Unterstützung für Forderungen sowie zum anschließenden Verschieben dieser Anwendungen zu Windows Azure. Teil 3 behandelt die Basisklasse, die Sie zum Einbinden der SharePoint-Website mit Azure-Daten verwenden werden, indem ein neues benutzerdefiniertes Steuerelement einer Seite im _layouts-Verzeichnis hinzugefügt wird. Teil 4 dokumentiert das Webpart, das mit dem CASI Kit geliefert wird, und beschreibt seine Verwendung, die verschiedenen Eigenschaften darin usw. In diesem letzten Beitrag werden zwei weitere wichtige Szenarien für dieses Kit erläutert: die Verwendung des in Teil 3 erstellten benutzerdefinierten Steuerelements zum Abrufen von Azure-Daten und zum Speichern dieser Daten im ASP.NET-Cache zur Verwendung durch andere Steuerelemente sowie die Verwendung des benutzerdefinierten Steuerelements in einer SharePoint-Aufgabe, in diesem Fall einem benutzerdefinierten SharePoint-Zeitgeberauftrag.

Verwenden des Steuerelements in anderen Webparts

Eins der wichtigen Szenarien, die unbedingt unterstützt werden müssen, stellt die Verwendung des CASI Kit-Frameworks zum Abrufen von Daten zur Verwendung in anderen SharePoint-Webparts dar. Es bleibt jedoch das andere Entwurfsziel, das darin bestand, KEINE routinemäßigen serverseitigen Aufrufe für möglicherweise latente WCF-Remoteendpunkte einzuführen. Um diese beiden voneinander abweichenden Anforderungen erfüllen zu können, implementiert die Basisklasse die Unterstützung für das Abrufen von Daten und für das Speichern der Daten direkt im ASP.NET-Cache. Dadurch können Sie andere benutzerdefinierte Webparts entwickeln und ein relativ einfaches Muster befolgen:

1. Überprüfen Sie, ob sich die Daten im ASP.NET-Cache befinden.

a. Ist dies der Fall, werden sie von dort abgerufen.

b. Gehen Sie andernfalls wie folgt vor:

                                                              i. Erstellen Sie eine Instanz des benutzerdefinierten Steuerelements.

                                                            ii. Legen Sie OutputType auf ServerCache fest und ServerCacheName und ServerCacheTime auf die entsprechenden Werte.

                                                          iii. Rufen Sie mit der ExecuteRequest-Methode die Daten ab.

Starten Sie zunächst ein neues Visual Studio-Projekt. In diesem Fall gehe ich von Visual Studio 2010 aus, sodass wir ein neues SharePoint 2010-Projekt erstellen können. Konfigurieren Sie das Projekt so, dass ein neues Webpart erstellt wird, und fügen Sie dann zwei Verweise hinzu: einen auf die CASI Kit-Basisklasse und einen auf das in Teil 3 erstellte benutzerdefinierte Steuerelement. Beachten Sie, dass bei einem fehlenden Verweis auf die CASI Kit-Basisklasse beim Festlegen einer beliebigen Eigenschaft im Steuerelement diese Eigenschaft von Visual Studio rot unterschlängelt wird. Und es wird eine Meldung angezeigt, dass die Eigenschaft nicht gefunden werden kann. Wenn diese Art von Fehler angezeigt wird, wissen Sie, dass Sie den Verweis auf die CASI Kit-Basisklasse nicht hinzugefügt haben.

Nachdem Sie die Verweise festgelegt haben, können Sie bei Bedarf Code für das Webpart schreiben. Dann kommen Sie irgendwann an den Punkt, an dem Sie Daten aus Azure abrufen müssen, sei es Inhalt, sein es Konfigurationsinformationen usw. Daher füge ich hier ein Beispiel für die Implementierung des oben beschriebenen Musters ein:

string CACHE_NAME = "AzureConfigConsumerCacheSample";

int CACHE_TIME = 10;

//create a var of the type of configuration data we want to retrieve

AzureWcfPage.CustomersWCF.Customer[] Customers = null;

//look for our item in cache

if (HttpContext.Current.Cache[CACHE_NAME] != null)

{

//if we find, it cast it to our type and pull it out of cache

       Customers =

(AzureWcfPage.CustomersWCF.Customer[])

HttpContext.Current.Cache[CACHE_NAME];

}

else

{

//if it's not in cache, then retrieve it and put it into cache

       //create an instance of the control

       AzureWcfPage.WcfDataControl cfgCtrl = new AzureWcfPage.WcfDataControl();

       //set the properties to retrieve data

       cfgCtrl.WcfUrl = "https://azurewcf.vbtoys.com/Customers.svc";

       cfgCtrl.OutputType = AzureConnect.WcfConfig.DataOutputType.ServerCache;

       cfgCtrl.ServerCacheName = CACHE_NAME;

       cfgCtrl.ServerCacheTime = CACHE_TIME;

       cfgCtrl.MethodName = "GetAllCustomers";

       //execute the method

       bool success = cfgCtrl.ExecuteRequest();

       if (success)

       {

//get the strongly typed version of our data

//the data type needs to come from the control we are creating

Customers =

(AzureWcfPage.CustomersWCF.Customer[])cfgCtrl.QueryResultsObject;

              //if you wanted the Xml representation of the object you can get

              //it from QueryResultsString

  string stringCustomers = cfgCtrl.QueryResultsString;

}

       else

       {

              //there was some problem; plug in your error handling here

       }

}

Sehen wir uns nun einen Teil des Codes etwas genauer an. Zunächst einmal sei hervorgehoben, dass Sie dem neuen Webpart KEINEN Dienstverweis auf den WCF-Endpunkt hinzufügen müssen. Dies alles ist in das benutzerdefinierte Steuerelement gekapselt, sodass Sie die Rückgabetypen der WCF-Anwendung verwenden können, die über das benutzerdefinierte Steuerelement offen gelegt werden. In dieser Codezeile wird dies demonstriert:

//create a var of the type of configuration data we want to retrieve

AzureWcfPage.CustomersWCF.Customer[] Customers = null;

In diesem Beispiel stellt AzureWcfPage die Assembly für mein benutzerdefiniertes Steuerelement dar. CustomersWCF ist der Name für meinen WCF-Dienstverweis. Und Customer ist der Klassentyp, der von meiner WCF-Methode zurückgegeben wird. All dies fließt in mein neues Webpart, wenn ich den Verweis der Assembly für mein benutzerdefiniertes Steuerelement hinzugefügt habe.

Zuerst einmal überprüfe ich, ob sich die Daten im Cache befinden. Ist dies der Fall, werden Sie in das Array der Customer-Instanzen umgewandelt, die ich dort zuvor gespeichert habe. Befinden sich die Daten nicht im Cache, schreiben Sie einfach die sieben Zeilen Code, die zum Erstellen einer Instanz des benutzerdefinierten Steuerelements und zum Abrufen der Daten erforderlich sind. Führen Sie folgende Schritte aus:

a. Erstellen Sie eine neue Instanz des Steuerelements

b. Legen Sie die Eigenschaften WcfUrl, MethodName, OutputType, ServerCacheName und ServerCacheTime fest.

c. Rufen Sie die ExecuteRequest-Methode auf.

Das ist alles. Falls die Methode erfolgreich beendet wird, wird der Rückgabewert aus der WCF-Anwendung im ASP.NET-Cache gespeichert, sodass bei der nächsten Ausführung dieses Codes das Element dort gefunden wird. Inzwischen kann ich die lokale Variable Customers in die QueryResultsObject-Eigenschaft des benutzerdefinierten Steuerelements umwandeln, und anschließend können die Daten vom Webpart nach Bedarf verwendet werden. Für die meisten Webpartentwickler sollte diese Aufgabe insgesamt relativ schnell und einfach zu implementieren sein.

Verwenden des Steuerelements in einer Aufgabe

Es folgt eine Beschreibung, wie das in Teil 3 entwickelte benutzerdefinierte Steuerelement zum Abrufen von Inhalt und/oder Konfigurationsdaten aus Azure verwendet wird, die anschließend in einer Aufgabe verwendet werden sollen. In diesem Beispiel habe ich einen benutzerdefinierten SharePoint-Zeitgeberauftrag geschrieben, in dem einige Daten aus Azure abberufen werden. Das Muster ist fast identisch wie beim oben beschriebenen Webpart, in diesem Fall ist jedoch wie bei den meisten Aufgaben kein HttpContext vorhanden, sodass der ASP.NET-Cache nicht verwendet werden kann. In diesem Fall ist OutputType auf None festgelegt, da die Daten weder in einer Seite gerendert noch im Cache gespeichert werden müssen. Stattdessen wird das Wertverzeichnis aus QueryResultsObject und/oder QueryResultsString abgerufen. Es folgt ein Codebeispiel hierzu. Es handelt sich um Code aus der Überschreibung der Execute-Methode in der benutzerdefinierten Zeitgeberauftragsklasse:

SPWebApplication wa = (SPWebApplication)this.Parent;

//create an instance of the control

AzureWcfPage.WcfDataControl cfgCtrl = new AzureWcfPage.WcfDataControl();

//set the properties to retrieve data

cfgCtrl.WcfUrl = "https://azurewcf.vbtoys.com/Customers.svc";

cfgCtrl.OutputType = AzureConnect.WcfConfig.DataOutputType.None;

cfgCtrl.MethodName = "GetAllCustomers";

//since there's no Http context in a task like a timer job, you also need to

//provide the Url to a claims-enabled SharePoint site. That address will be used

//to connect to the STS endpoint for the SharePoint farm

cfgCtrl.SharePointClaimsSiteUrl = wa.Sites[0].RootWeb.Url;

//execute the method

bool success = cfgCtrl.ExecuteRequest();

//check for success

if (success)

{

//now retrieve the data and do whatever with it

       AzureWcfPage.CustomersWCF.Customer[] Customers =

(AzureWcfPage.CustomersWCF.Customer[])cfgCtrl.QueryResultsObject;

       string AzureResults = cfgCtrl.QueryResultsString;

//this is where you would then do your tasks based on the data you got from Azure

foreach(AzureWcfPage.CustomersWCF.Customer c in Customers)

       {

Debug.WriteLine(c.Email);

       }

       Debug.WriteLine(AzureResults);

}

else

{

//do something to log the fact that data wasn't retrieved

}

Es folgen ein paar weitere Erläuterungen zu diesem Code. Bei dem Zeitgeberauftrag handelt es sich um einen Auftrag im Bereich der Webanwendung, daher wird zunächst ein Verweis auf das SPWebApplication-Objekt abgerufen, für das dieser Auftrag ausgeführt wird, indem auf die Parent-Eigenschaft verwiesen wird. Dann erstelle ich das benutzerdefinierte Steuerelement aus Teil 3 und lege die minimalen Eigenschaften fest, die zum Abrufen von Daten aus Azure erforderlich sind. In der nächsten Codezeile muss die SharePointClaimsSiteUrl-Eigenschaft festgelegt werden. Wie in Teil 3 bereits erläutert, wird bei Ausführung der CASI Kit-Basisklasse über die ExecuteRequest-Methode überprüft, ob ein HttpContext verfügbar ist. Ist dies der Fall, wird dieser Kontext zur Ermittlung der aktuellen SharePoint-Website-URL verwendet, und die Verbindung mit dem SharePoint-STS wird über diese Website hergestellt. Wie oben bereits beschrieben ist in der Regel kein HttpContext vorhanden, wenn der Code in einer Aufgabe ausgeführt wird. In diesem Fall kann die Basisklasse nicht bestimmen, welche URL verwendet werden soll, um eine Verbindung mit dem SharePoint-STS herzustellen. Daher muss in diesem Fall die URL zu einer Website in einer Webanwendung mit Unterstützung für Forderungen angegeben werden. Im Code des Zeitgeberauftrags in dieser Implementierung wird vorausgesetzt, dass er NUR in Webanwendungen mit Unterstützung für Forderungen ausgeführt wird. Dies ist der Grund, warum der Verweis auf die aktuelle Webanwendung verwendet und die URL zur ersten Websitesammlung dann einfach übergeben wird. Dabei ist es egal, welche Websitesammlung verwendet wird, solange sich diese in einer Webanwendung mit Unterstützung für Forderungen befindet.

Wenn die SharePointClaimsSiteUrl-Eigenschaft festgelegt wurde, kann wie zuvor bereits gezeigt die ExecuteRequest-Methode aufgerufen werden. Wird sie erfolgreich ausgeführt, können die Daten direkt über die Eigenschaften QueryResultsObject und/oder QueryResultsString aus dem Steuerelement abgerufen werden.

Sowohl das Webpartprojekt als auch das Projekt für den Zeitgeberauftrag sind in der ZIP-Datei enthalten, die an diesen Beitrag angefügt ist.

Das wäre geschafft!

Dies ist der letzte Beitrag in dieser Serie. Hoffentlich konnte ich Ihnen das CASI Kit etwas näher bringen. Und Sie wissen nun, dass Sie relativ einfach eine Verbindung zu Daten herstellen können, die in einer WCF-Anwendung auf einer Website oder in der Cloud gehostet werden, während das Benutzeridentitätstoken über die Grenzen von Anwendungen und sogar Rechenzentren hinweg verwendet werden kann. Zusammengefasst ist das Muster relativ einfach zu implementieren:

1. Erstellen Sie ein WCF-Front-End für Ihren Inhalt und/oder Ihre Konfigurationsdaten. Aktivieren Sie die Unterstützung für Forderungen, und verschieben Sie die Anwendung optional in die Cloud. Implementieren Sie optional Entscheidungen zu einer weiteren Differenzierung der Berechtigungen auf der Grundlage der aufrufenden Benutzeridentität und der Forderungen.

2. Schreiben Sie ein benutzerdefiniertes Steuerelement, das von der CASI Kit-Basisklasse erbt. Überschreiben Sie eine Methode, und schreiben Sie fünf Codezeilen. Fügen Sie das Steuerelement der layouts-Seite hinzu, und stellen Sie es bereit.

3. Fügen Sie das Webpart einer Seite hinzu, legen Sie mindestens eine Eigenschaft fest, und beginnen Sie mit dem Rendern Ihrer WCF-Daten. Verwenden Sie das Steuerelement optional zum Abrufen von Inhalt oder von Konfigurationsdaten in einem benutzerdefinierten Webpart oder in einer Aufgabe wie einem benutzerdefinierten Zeitgeberauftrag.

Das ist schon alles. Ich hoffe, dass ein Teil der Fragen und Schwierigkeiten beim Verbinden der SharePoint-Farm mit Daten, die irgendwo auf dieser Welt gespeichert sind, durch das CASI Kit gelöst werden können. Es kann genauso auch zum Abrufen von Konfigurationsdaten oder persönlichen Daten verwendet werden sowie zum Abrufen von Inhalt, der auf Ihren SharePoint-Websites angezeigt werden soll. Und nun können Sie flexibel die in der Organisation implementierte Sicherheit auch über die Grenzen von Anwendungen und Rechenzentren hinweg verwenden. Mir hat die Ausfertigung, das Entwerfen und Entwickeln dieser Serie sehr viel Spaß gemacht, und ich hoffe, dass Sie Ihnen sehr nützlich sein wird. Wie immer handelt es sich hierbei nur um eine erste Veröffentlichung. Und ich bin sicher, dass sich noch Einiges verbessern lässt. Ich freue mich daher über Kommentare und Anregungen zu diesen Beiträgen. Ich werde sie regelmäßig lesen und mir für die nächste größere Veröffentlichung entsprechende Gedanken machen.

Es handelt sich hierbei um einen übersetzten Blogbeitrag. Sie finden den Originalartikel unter The Claims, Azure and SharePoint Integration Toolkit Part 5