2016-04-19 12 views
0

Ich experimentiere mit dem Lesen von SharePoint 2013 Site Column Metadaten aus einem Word 2010 C# VSTO auf Anwendungsebene.SharePoint Benutzerfeld lesen/schreiben [Word 2010 VSTO]

Zum Testen habe ich Site Columns für jeden von SharePoint verwendeten Typ eingerichtet und dann einen Dokument-Inhaltstyp erstellt, der mit allen verknüpft ist. Daher werden alle diese Spalten in das Word-Dokument eingebettet customXml in der Dokumentdatei).

Durch Lesen der _Document.ContentTypeProperties Eigenschaft innerhalb der VSTO-Code, kann ich auf die meisten Typen zugreifen, aber ich habe Schwierigkeiten beim Zugriff auf eine 'Person oder Gruppe' Site-Spalte Daten - Ich bekomme COM-Ausnahmen versuchen zu lesen oder zu schreiben zur .Value Eigenschaft eines Artikels.

im XSD-Schema in CustomXML Durch suchen, kann ich einen Single-Wert Spalte User sehen aus drei Werten zusammen: DisplayName (Typ string), AccountType (Typ string) und AccountId (Typ UserId) - aber ich sehen Sie keine Möglichkeit, innerhalb des VSTO von/zu lesen/schreiben? Mehrwertige Benutzerspalten scheinen völlig verschieden zu sein und setzen sich aus zwei Werten zusammen: einer ID (scheint die SharePoint-Benutzer-ID zu sein) und einer string-basierten ID (oder zumindest ist das, was ich denke, die i:0#.w|domain\userid ist sowieso).

Word selbst kann sowohl ein- als auch mehrwertige Benutzerspaltedaten über das Dokumentfenster bearbeiten, jedoch nur, wenn Word derzeit mit SharePoint verbunden ist - andernfalls ist die Funktionalität deaktiviert. Ich würde nehmen das gleiche würde für die VSTO wahr sein, wenn ich alle Werte zugreifen konnte ...

Meine beiden Fragen sind:

  1. Gibt es eine Möglichkeit zum Lesen/Schreiben Ein- und mehrwertige Benutzerfelder aus dem VSTO-Code (auch wenn es nicht über die _Document.ContentTypeProperties-Eigenschaft geht)?

  2. Gibt es eine Möglichkeit, Q1 auszuführen, wenn keine Verbindung zu SharePoint besteht (wenn die Werte beispielsweise dem Code bekannt sind)?

(Ich habe meine Arbeitsweise ist in dem Fall etwas allzu weitschweifig gewesen jemand anderen sogar so weit sinnvoll, wenn ich keine Antwort bekommen, es nicht eine große Menge an Informationen über diese überall zu sein scheint)

Antwort

0

Mit einigen Vorbehalten glaube ich, dass Sie diese Felder mit VSTO lesen/aktualisieren können - obwohl ich nicht tatsächlich ein funktionierendes Beispiel mit VSTO erstellt habe, sind die gleichen Objekte, die ich in Word VBA verwenden würde verfügbar - die Codefragmente unten sind VBA.

Die Personen-/Gruppenwerte, die im DIP angezeigt werden, werden in einem benutzerdefinierten XML-Teil gespeichert, auch wenn der SharePoint-Server nicht verfügbar ist. Das Problem besteht also nicht darin, die Werte zu ändern - es ist im Wesentlichen eine CRUD-Operation -, sondern zu wissen, welche Werte Sie verwenden können, insbesondere im mehrwertigen Fall. Wenn Sie wissen, wie Sie gültige Werte konstruieren (sagen wir, Sie haben eine unabhängige Liste von E-Mail-Adressen), dann können Sie die Änderungen lokal vornehmen. Persönlich weiß ich nicht, wie ich einen gültigen Wert für den mehrwertigen Fall erstellen würde, also müsste ich im Grunde den Server kontaktieren.

So vorausgesetzt, Sie die Daten, die Sie lokal aktualisieren müssen ...

Wenn Sharepoint ein Word-Dokument dient, fügt er/updates mehrere benutzerdefinierte XML-Parts. Einer enthält eine Reihe von Schemas (wie Sie herausgefunden haben). Ein anderer enthält die Daten. Sie müssen nur auf das korrekte benutzerdefinierte XML-Teil zugreifen, das XML-Element finden, das Ihrer SharePoint-Benutzer-/Gruppenspalte entspricht, dann ist es eine CRUD-Operation auf den Unterelementen dieses Elements.

Sie können das korrekte benutzerdefinierte XML-Teil mit dem entsprechenden Namespace-Namen finden, z.

Const metaPropDataUri as String = _ 
    "http://schemas.microsoft.com/office/2006/metadata/properties" 
Dim theDoc as Word.Document 
Dim cxp as Office.CustomXMLPart 
Dim cxps as Office.CustomXMLParts 
Set theDoc = ActiveDocument 
Set cxps = theDoc.CustomXMLParts.SelectByNamespace(metaPropDataUri) 

Wenn es mehr als ein Teil assoziiert mit diesem Namensraum ist, ich weiß nicht genau, wie die richtigen zu wählen. AFAIK Word/Sharepoint erstellt immer nur eins, und Experimente schlagen vor, dass, wenn es ein anderes gibt, SharePoint mit dem ersten arbeitet. So verwende ich

An dieser Stelle müssen Sie den XML-Element-Namen der Person/Gruppe-Spalte kennen. Es kann mit dem externen Namen identisch sein (der Name, der in der SharePoint-Liste angezeigt wird), aber wenn beispielsweise jemand die Sharepoint-Spalte "Personengruppe" aufgerufen hat, lautet der Elementname "person_x0020_group". Wenn der Name nicht variiert, können Sie ihn aus dem XML-Schema des Schemas als einmalige Aufgabe abrufen. Oder es kann einfach sein, den richtigen Elementnamen aus einem beliebigen SharePoint-Namen zu generieren.Andernfalls können Sie es dynamisch aus dem Schema XML erhalten, die Sie (als String) erhalten können

theDoc.ContentTypeProperties.SchemaXML 

mit Was Sie tun müssen, dann ist das Element finden mit dem Attribut ma: display = „der externe Name“ und erhalte den Wert des Namensattributs. Ich könnte mir vorstellen, dass ganz einfach ist mit C#, ein geeignetes XML-Objekt, und ein wenig XPath, sagen

//xsd:element[@ma:displayName='person group'][1]/@name 

die ‚person_x0020_group‘

zurückkehren sollte können Sie dann das Element Knoten für Ihre Daten erhalten, z.B. etwas entlang der Linien von

Dim cxn As Office.CustomXMLNode 
Set cxn = cxp.SelectSingleNode("//*[name()='person_x0020_group'][1]") 

Oder Sie können es bevorzugt, finden die NamespaceURI der Elemente in dieser benutzerdefinierten XML-Abschnitt zu erhalten und verwenden, die Sie suchen Sie den richtigen Knoten zu helfen. Der Name ist eine lange Hex-Zeichenfolge, die von SharePoint zugewiesen wird. Sie können es aus der Schema-XML unter Verwendung von z.

//xsd:schema[1]/@targetNamespace 

Sobald Sie Ihren Knoten haben, würden Sie die bekannten Strukturen verwenden (das heißt die, die Sie in den Schemen gefunden haben) zu erhalten/ändern/erstellen geordneten Knoten nach Bedarf.

+0

Ich dachte, ich müsste die customXml-Daten direkt modifizieren - ich hatte gehofft, dass ich nicht nur für einen Typ brauchen würde. Ich schaue mir das an - danke! – Reznikk

+0

Ja, AFAICS gibt es keine Schnittstelle, die die interne Struktur des ContentTypeProperty-Objekts für diesen Eigenschaftstyp verfügbar macht. –

+0

Vielen Dank für Ihre Mühe - und während dies sicherlich die einzige verfügbare Option ist, würde ich es gerne kurz "richtig" markieren, für den Fall, dass eine andere mögliche Lösung erscheint (Sie wissen nie mit VSTO Zeug ...). – Reznikk

0

natürlich können Sie. Sie sollten das SharePoint-Client-seitige Objektmodell (CSOM) verwenden, um SharePoint-Daten von einem vom Server entfernten Speicherort zu bearbeiten. Sie benötigen lediglich die URL Ihrer SharePoint-Website.

Sie können dann durch CSOM wie folgt verbinden:

ClientContext context = new ClientContext("SITEURL"); 
Site site = context.Site; 
Web web = context.Web; 
context.Load(site); 
context.Load(web); 
context.ExecuteQuery(); 

Sehen Sie hier ein Beispiel eines einzelnen Benutzerfeld zu setzen:

zuerst die ID des Benutzers erhalten durch den Benutzernamen gewährleistet

u = context.Web.EnsureUser(UserOrGroupName); 
context.Load(u); 
context.ExecuteQuery(); 

Um den Wert zu setzen, können Sie dieses Zeichenfolgenformat verwenden:

userid;#userloginname;# 

den Feldeinsatz setzen dies:

item[myusercolumn] = "userid;#userloginname;#"; 
item.Update(); 
context.ExecuteQuery(); 

ein Multi-User-Feld zu setzen, können Sie den gleichen Code verwenden können, verwenden Sie einfach; # die verschiedenen Benutzernamen verketten, wie zum Beispiel:

item[myusercolumn] = "userid1;#userloginname1;#userid2;#userloginname2;#userid3;#userloginname3;#"; 
item.Update(); 
context.ExecuteQuery(); 

+0

Vielen Dank für Ihre Antwort, aber Ihre Methode ist zum Ändern der Daten in SharePoint direkt, anstatt der Daten im Word-Dokument enthalten - daher beim Speichern des Dokuments zurück in SharePoint, würde es sicherlich Änderungen mit Ihrem überschrieben Ansatz? – Reznikk

+1

Ok Entschuldigung, ich habe deine Frage falsch gelesen. Dann kann ich nur sagen, dass in der "stringbasierten ID", wie Sie es nennen, dies tatsächlich ein nach Anspruch codierter Benutzername ist. Das Präfix 'i: 0 # .w |' teilt SharePoint mit, ob es ein Benutzer oder eine Gruppe (i oder c) ist und welcher Authentifizierungstyp verwendet wird (w: windows auth, f: formularbasiert) – Verthosa

+0

Das ist eigentlich sehr nützlich zu wissen, danke! – Reznikk