Sharepoint 2010 Listen Feld Person/Group mit Webservice füllen

Category: C#
05.06.2011
Author: Robert Fink
Aufrufe: 6275

Personalisierte Listen

Ein wirklich nützliches Feature in Sharepoint Listen ist die Möglichkeit mittels eines Filters nach dem angemeldeten Benutzer zu filtern. Das gibt die Möglichkeit für große Listen einen View zu erstellen in dem nur die Daten des gerade anfragenden Benutzers ausgegeben werden. Damit brauche ich keine große Abfrage Logik im Hintergrund sondern bekomme diese Funktionalität quasi frei Haus mit ein paar Klicks geliefert.

Genau vor so eine Aufgabe wurde ich gestellt und ich sollte eine Tabelle mit ca. 2000 Einträgen online stellen bei der jeder Benutzer nur seine Einträge sieht. Die Liste importieren ist ja kein Problem. In einem Feld der Liste ist auch der Anmeldenamen  enthalten. Also so dachte ich kann ich danach ja wohl filtern.

Wie sich aber herausstellte muss für die angesprochene Filtermöglichkeit ein Feld vom Typ Person/Gruppe vorhanden sein. So wie füllt man dieses Feld aber korrekt?

Schaut man sich diesen Feldtyp etwas genauer an so sieht man, dass es eigentlich ein Zahlenfeld ist und wie sich herausstellt wird hier eine ID gespeichert. Doch woher kommt jetzt diese ID?

Füllt man ein solches Feld direkt über die Weboberfläche vom Sharepoint so passiert folgendes. Der angegebene Username wird im aktuellen Domain Forrest im AD abgefragt und einige AD Daten werden in eine Systemtabelle im Sharepoint übertragen, dabei wird für den User eine ID vergeben, wenn er in dieser Systemtabelle noch nicht vorhanden ist. Ist er schon in der Systemtabelle so wird die bestehende ID verwendet.

Diese ID wird in das Person/Gruppe Feld eingetragen und beim Rendering der Tabelle werden dann die Daten gemäß der Felddefinition angezeigt.

Wie nun per Code?

People Webservice

Es gibt sicher mehr Möglichkeiten diese Aufgabe zu erfüllen. Wenn man vollen Zugriff auf den Sharpoint hat und da auch customized Code ablegen kann, könnte man z.B. die Importroutine für die Liste modifizieren. Ich hatte aber die Problemstellung, dass ich zwar Adminrechte auf dem Sharepoint habe aber aus Sicherheits- und Wartungsgründen keinen customized Code einsetzen darf. Also musste ich einen anderen Weg finden. Nach ein bisschen Recherche fand ich die Möglichkeit mittels SOAP Webservices genau dieses auszuführen.  

So wie funktioniert das nun? Ich habe das ganze als kleines Tool in Visual Studio und C# umgesetzt. Um auf die Webservices zuzugreifen muss man den Webservice als Webservice Verweis im Projekt eintragen. Die Webservices residieren in dem Verzeichnis servername/sitename/_vti_bin/  Im diesem Projekt verwende ich zwei Webservices. Zum einen den Person Webservice um die ID des Users zu ermitten und dann den Lists Webservice um die entsprechende Liste mit den Daten zu befüllen.

Nachdem ein Visual Studio Projekt angelegt ist kann man per Rechtsklick im Projektmappen Explorer auf Service Referenzen einen Service Verweis hinzufügen. Wir brauchen einen Web Verweis dazu klicken wir auf 'Erweitert' im nächsten Fenster dann auf den Button 'Webverweis hinzufügen'. Im URL Feld tragen wir jetzt die Adresse zu dem Webservice eine. Für  den Lists Service lautet die servername/sitename/_vti_bin/Lists.asmx.  Dann klickt man auf den grünen Pfeil. Ist alles richtig werden nun die verfügbaren Methoden des Webservice angezeigt. Jetzt geben wir nun einen passenden Namen ein und klicken auf Verweis hinzufügen. Das gleiche machen wir jetzt noch für den Person Webservice.

Jetzt kann man den Webservice ansprechen.  Als erstes benutze ich den Person Webservice (PersonWS) um die benötigte ID für einen User zu ermitteln, da ich das ja in die Liste einfügen will. Als erstes gilt es natürlich ein Objekt zu und erzeugen. Um auf den Sharepoint zugreifen zu können muss man sich natürlich authentifizieren. Dazu übergeben wir der Eigenschaft Credentials die Credentials des gerade angemeldeten Benutzers aus dem Credential Cache. Der Eigenschaft URL übergeben wir  die URL zur People.asmx.

PeopleWS.People pe = new PeopleWS.People();
pe.Credentials = System.Net.CredentialCache.DefaultCredentials;
pe.Url = "http://servernam/sitename/_vti_bin/People.asmx>";

Die URL Eigenschaft muss man setzen, obwohl wir ja eigentlich die URL schon beim anlegen des Webservice eingetragen haben. Macht man das nicht und der Sharepoint ist eine Instanz in einer Sharepoint Farm so gibt die Anfrage nicht die korrekte ID zurück. Das liegt daran, dass die Sharepointfarm selbst auch noch eine ID Liste führt und die unterscheidet sich natürlich von der ID der Instanz.

Nun können wir mit der Methode PrincipalInfo die ID abfragen. Dazu übergeben wir den Benutzernamen im Format Domäne\SamAccountName als String, wählen als Rückgabewert SPPrincipalType.User. Zusätzlich kann man noch ,true hinzufügen. Das führt dann dazu, dass der Benutzer, sollte er in der Liste noch nicht bekannt sein neu angelegt wird.

PeopleWS.PrincipalInfo[] principleInfoUser = pe.ResolvePrincipals("domain\SamAccountName", PeopleWS.SPPrincipalType.User, true);

Vom Webservice bekommen wir ein Array principleInfoUser. Hier holen wir uns dann die ID und bringen sie in ein Format mit der wir sie dann an den Lists Webservice übergeben können.

string UserID = principleInfoUser[0].UserInfoID.ToString();
string UserFormat = principleInfoUser[0].UserInfoID.ToString() + ";#" + principleInfoUser[0].AccountName.ToString();

Lists Webservice

So jetzt könne wir uns dem Lists Service widmen. Der Beginn ist identisch zum People Webservice. Ein Objekt erzeugen und Credentials und die URL übergeben.

ListsWS.Lists li = new ListsWS.Lists();
li.Credentials = System.Net.CredentialCache.DefaultCredentials;
li.Url = "http://servername/sitename/_vti_bin/Lists.asmx";

Da sich auf einem Sharepoint ja viele Listen befinden können und für jede Liste auch noch mehrere Views hinterlegt sein können müssen wir dem Webservice mitteilen mit welcher Liste und welchem View wir arbeiten wollen. Da Namen eventuell doppelt vorkommen könnten muss man hier sowohl für die Liste als auch den View die GUID übergeben. Es gibt Tools, mit denen man alle nötigen GUIDs auslesen kann, wie zum Beispiel hier.

Einfacher ist es aber das ganze per Code zu bewerkstelligen. Dazu verwenden wir die Methode GetListAndView und übergeben den Listennamen und den Viewnamen. Lassen wir den Viewnamen leer so wird die GUID des Default Views zurück gegeben.

System.Xml.XmlNode ndlistview = li.GetListAndView("Listname", "");
string strListID = ndlistview.ChildNodes[0].Attributes["Name"].Value;
string strViewID = ndlistview.ChildNodes[1].Attributes["Name"].Value;

Jetzt können wir uns die GUIDs zur weiteren Verwendung in Variablen speichern. 

Als nächstes müssen wir uns ein ein Batch in XML bauen, das wir dann an den Webservice übergeben können.

string strBatch = "<Method ID='1' Cmd='New'>" +
"<Field Name='Title'>" + name + "</Field>" +
"<Field Name='Vorname'>" + vorname + "</Field>" +
"<Field Name='ADAlias' Type='User' frombasetype='FALSE'>" + UserFormat + "</Field>" +
"</Method>";

Wobei man jedes Listenfeld, das man befüllen möchte als <Field Name=###>...</Field> definieren muss. Ein kleiner Tip sei hier noch angebracht. Legt man ein Listenfeld an und ändert nachträglich den Namen so ist das Feld nur unter alten Namen ansprechbar. Auch wenn man den Sharepoint deutsch aufgesetzt hat werden hier oft die englischen Namen verwendet. Wenn man das nicht beachtet kann man sehr lange nach dem Fehler suchen. Der einfachste Weg für mich den korrekten Feldnamen zu bekommen ist im Sharepoint in die Listeneinstellungen zu gehen und den Mauszeiger über die einzelnen Feldnamen zu bewegen. Bei dem Link, der angezeigt wird befindet sich der zu verwendende Feldname am Ende.

So nun könne wir uns das benötigte XML zusammen bauen.

XmlDocument xmlDoc = new System.Xml.XmlDocument();
System.Xml.XmlElement elBatch = xmlDoc.CreateElement("Batch");
elBatch.SetAttribute("OnError","Continue");
elBatch.SetAttribute("ListVersion", "1");
elBatch.SetAttribute("ViewName", strViewID);
elBatch.InnerXml = strBatch;

Als Attribute übergibt man das Verhalten bei einem Fehler, die Listen Version, die aber meistens 1 ist und die GUID des Views.

So jetzt wird es Ernst mit der Methode UpdateListItems erzeugen wir jetzt einen neuen Eintrag.

XmlNode ndReturn = li.UpdateListItems(strListID, elBatch);
if (ndReturn.InnerText != "0x00000000")
{
MessageBox.Show(name,vorname,ndReturn,OuterXML);
}

Der Webservice gibt ein XML mit dem Ergebnis zurück. Ich lass mir bei fehlgeschlagenen insert die Werte und das Ergebnis XML anzeigen. Gibt der Webservice ein 0x00000000 im XML zurück hat der insert funktioniert.

So ich hoffe das ganze hier hilft vielleicht jemanden weiter.

Keine Kommentare
Kommentar hinzufügen

* - Pflichtfeld

*




CAPTCHA-Bild zum Spam-Schutz Wenn Sie das Wort nicht lesen können, bitte hier klicken.

*
*

Suchen & Finden

Kalender