SharePointCommunity
Die deutschsprachige Community für SharePoint, Microsoft 365, Teams, Yammer und mit Azure

Sponsored by

Willkommen im Forum Archiv.
Einträge sind hier nicht mehr möglich, aber der Bestand von 12 Jahren SharePoint-Wissen ist hier recherchierbar.




Event Receiver 2 Listen synchronisieren

Unbeantwortet Dieser Beitrag hat 14 Antworten

Ohne Rang
26 Beiträge
Martin_ erstellt 27 Sept. 2016 16:47
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Guten Tag, 

ich habe jetzt ewig im Internet gesucht und einige Dinge auch gefunden aber diese funktionierten bei mir nicht.

Ich möchte mit einem Event Receiver 2 Listen synchronisieren.

Wenn in Liste 1 ein neuer Eintrag erstellt wird, soll dieser auch in Liste 2 erstellt werden (durch den Event Receiver). Wenn in Liste 1 der Eintrag bearbeitet wird soll diese Änderung auch in der 2. liste geändert werden; das selbe auch wenn der Eintrag gelöscht wird.

Wenn mit jemand bei dieser Aufgabe helfen könnte wäre ich sehr dankbar.

Ich nutze Visual Studio 2013 und habe SharePoint 2013 Foundation im Einsatz.

Grüße

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 27 Sept. 2016 17:09
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Vermutlich wird Dir hier niemand eine komplette Lösung posten. Deshalb die Nachfrage: wo genau klemmt's denn? Es ist deutlich einfacher (und geht schneller) ein Detail zu erklären...

Jedenfalls mußt Du in Liste 2 in einem (versteckten) Feld die ID des Elements aus Liste 1 speichern, damit Du immer einen Zusammenhang herstellen kannst. Behandle dann in Liste 1 ItemAdded, ItemUpdated und ItemDeleted.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
26 Beiträge
Martin_ Als Antwort am 27 Sept. 2016 18:07
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich möchte nach dieser Anleitung den Event Receiver erstellen. http://stackoverflow.com/questions/34760022/how-to-synchronize-two-lists-in-two-different-spsites-using-event-receivers 

Wenn ich den Code geschrieben habe bekomme ich folgenden Fehler:

 

 

var

 

 

syncedItem = from SPListItem item in list2Items where Convert.ToString(item["list1Item"]).Equals(properties.ListItem.ID.ToString()) select item; -> Fehler  Es konnte keine Implementierung des Abfragemusters für den Quelltyp "Microsoft.SharePoint.SPListItemCollection" gefunden werden. "Cast" wurde nicht gefunden. Möglicherweise fehlt ein Verweis oder eine Using-Direktive für "System.Linq". 

Ich habe dann using System.Linq; hinzugefügt. Danach bekam ich diese Fehler:

syncedItem[

 

"Title"] = properties.ListItem["Title"]; -> Fehler Indizierung mit [] kann nicht auf einen Ausdruck vom Typ "System.Collections.Generic.IEnumerable<Microsoft.SharePoint.SPListItem>" angewendet werden. 

syncedItem.Update(); -> Fehler "System.Collections.Generic.IEnumerable<Microsoft.SharePoint.SPListItem>" enthält keine Definition für "Update", und es konnte keine Erweiterungsmethode "Update" gefunden werden, die ein erstes Argument vom Typ "System.Collections.Generic.IEnumerable<Microsoft.SharePoint.SPListItem>" akzeptiert. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)

 

 

 

 

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 28 Sept. 2016 08:19
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Dein Code riecht sehr nach Linq2SharePoint (was nirgendwo hinter Deinem Link auftaucht). Ich selbst habe damit nie gearbeitet, aber damit das funktioniert, muß soweit ich weiß noch etwas installiert werden.

Ich würde Dir empfehlen mit einem ganz simplen EventReceiver anzufangen und Dich dann langsam vorzutasten.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
26 Beiträge
Martin_ Als Antwort am 28 Sept. 2016 09:27
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich habe auch folgendes Beispiel probiert aber das macht irgendwie gar nichts wenn ich einen Eintrag erstelle/bearbeite.

public override void ItemUpdated(SPItemEventProperties properties)
{
    base.ItemAdded(properties);
    using (SPSite site = new SPSite(properties.WebUrl))
    {
       using (SPWeb web = site.OpenWeb())
       {
          web.AllowUnsafeUpdates = true;
          SPListItem item = properties.AfterProperties;
          var aValue= item["A"].ToString();

          SPList syncList = web.Lists["SecondList"];
          SPListItem syncItem = syncList.GetItemById(properties.ListItemId)
          syncItem["A"] = aValue;
          syncItem.Update();
        }
    }
}
Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 28 Sept. 2016 09:47
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Baue eine ordentliche Fehlerbehandlung inkl. Protokollierung in die SharePoint Trace Logs ein, dann siehst Du, was da genau passiert. Und verwende einen Debugger...

[quote user="Martin_"]SPListItem item = properties.AfterProperties;[/quote]

Die Zeile schmeißt einen Fehler, weil AfterProperties ein Dictionary ist und kein SPListItem. Das sollte Dir aber Visula Studio schon beim Kompilieren sagen.

Was sonst so auffällt:

  • Du bist in ItemUpdated, rufst aber base.ItemAdded
  • Du erzeugst völlig unnötig ein neues SPSite und ein neues SPWeb Objekt. Benutze einfach properties.Web - ohne using.
  • Du bist in ItemUpdated, greifst aber auf AfterProperties zu. Die sind hier immer leer. Benutze stattdessen properties.ListItem.
  • Du suchst in der zweiten Liste per GetItemById und benutzt dabei die ID des Elements der ersten Liste. Die werden in der Praxis niemals identisch sein. Gebe der zweiten Liste ein zusätzliches Feld und schreibe dort die ID aus der ersten Liste hinein.
Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
26 Beiträge
Martin_ Als Antwort am 29 Sept. 2016 12:34
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Habe nun mit einem einfachen Event Receiver begonnen und Schritt für Schritt weiter gemacht. 

Bei einigen Dingen habe ich noch Probleme. 

Der Termin in der 2. Liste bekommt immer das Start Date von der Uhrzeit als ich den Termin erstellt habe und nicht jene Uhrzeit welche ich im Termin in der Liste 1 eingetragen habe.

newItem["Start Date"] = properties.ListItem["Start Date"]; 

 

Und wenn ich den Termin in der Liste 1 lösche, löscht es den Termin in der 2. Liste nicht:

 SPListItemCollection item = list.GetItems(query);

                        SPListItem newItem = item[0];              

                        newItem.Delete();

 

Sobald ich eine Änderung mache und das Projekt in Visual Studio Bereitstelle, werden immer alle Einträge von der Liste gelöscht. Wie kann man das verhindern?

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 29 Sept. 2016 13:54
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Martin_"]newItem["Start Date"] = properties.ListItem["Start Date"];[/quote]

"Start Date" ist der sichtbare Name der Spalte und den sollte man im Code immer vermeiden. Verwende stattdessen den unveränderlichen InternalName. Du findest ihn z.B., indem Du in den Listeneinstellungen auf die Spalte klickst. In der Adresszeile steht dann Field=<InternalName>

[quote user="Martin_"]Und wenn ich den Termin in der Liste 1 lösche, löscht es den Termin in der 2. Liste nicht:

 SPListItemCollection item = list.GetItems(query);

                        SPListItem newItem = item[0];              

                        newItem.Delete();[/quote]

Wie sieht die query denn aus? Bist Du sicher, daß überhaupt etwas gefunden wird? Du solltest das auch prüfen, bevor Du mit item[0] darauf zugreifst. Es könnte ja auch von einem Benutzer gelöscht worden sein.

[quote user="Martin_"]Sobald ich eine Änderung mache und das Projekt in Visual Studio Bereitstelle, werden immer alle Einträge von der Liste gelöscht[/quote]

Wenn die Listen ebenfalls über die Solution bereitgestellt werden, dann löscht Visual Studio immer die ganzen Listen. Man kann das nur verhindern, indem man die Bereitstellung nicht Visual Studio überläßt, sondern selbst erledigt. Z.B. per PowerShell Upgrade-SPSolution

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
26 Beiträge
Martin_ Als Antwort am 29 Sept. 2016 15:30
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Das habe ich bereits versucht aber wenn ich statt Start Date den InternalName "EventDate" verwende erstellt es mir in der 2. Liste gar keinen Eintrag.

 

Die query sieht so aus. 

SPQuery query = new SPQuery();

query.Query = "<Where><Eq><FieldRef Name='Zahl'/><Value Type='Text'>" + "Liste1_" + properties.ListItem.ID + "</Value></Eq></Where></Query>";

Finden tut er den Eintrag, denn wenn ich den Eintrag ändere dann ändert es den Eintrag auch in der 2. Liste. 

Aber wenn ich den Eintrag in der 1. Liste lösche dann wird er in der 2. Liste nicht gelöscht.

 

Vielen Dank für den Tipp mit PowerShell Upgrade-SPSolution.

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 29 Sept. 2016 16:17
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Zum Löschen: Du verwendest in der Query properties.ListItem.ID. Wenn Du das in ItemDeleted versuchst, kann es nicht gehen, weil es kein ListItem mehr gibt. Es wurde ja bereits gelöscht. Verwende properties.ListItemId.

Und nochmal der Hinweis: wenn Du eine Fehlerbehandlung mit Protokollierung oder einen Debugger einsetzen würdest, hättest Du das selbst herausgefunden. Das soll übrigens kein Gemecker von mir sein, sondern ein hilfreicher Tip zum Besserwerden :-)

Zum Thema mit dem Datum kann ich nichts sagen. Ich vermute, daß irgendwas mit den Namen oder den Datentypen nicht stimmt. Ich verwende grundsätzlich immer nur InternalName.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
391 Beiträge
Frank Daske Als Antwort am 11 Okt. 2016 10:02
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo zusammen,

noch als Nachtrag: Um SharePoint on-prem oder SharePoint Online / Office 365 Listen mit anderen Listen oder auch mit nahezu beliebigen externen Datenquellen synchron zu halten, gibt's auch sofort einsatzbereite Tools - ohne jede Programmierung:

http://www.layer2solutions.com/de/produkte/Seiten/default.aspx

Auf den ersten Blick geht das natürlich über PowerShell oder Event-Receiver auch. Allerdings steckt der Teufel im Detail. Die Tools sind seit Jahren bei tausenden von Kunden im Einsatz, da steckt bereits einiges an Erfahrung drin. Also wenn es schnell gehen und sicher funktionieren soll - einfach mal ausprobieren.

Die folgenden Systeme werden unterstützt:
http://www.layer2solutions.com/en/solutions/Pages/default.aspx

Beste Grüße, Frank.

 

Ohne Rang
26 Beiträge
Martin_ Als Antwort am 11 Okt. 2016 10:53
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Guten Tag, 

da ich auf der Suche nach einer gratis Lösung für mein Problem bin, ist die Layer2 Lösung nicht das richtige für mich. Vielen Dank trotzdem für den Tipp. 

Derzeit bin ich bei einigen Tests mit dem Event Receiver und versuche mit diesem mein Problem zu lösen.

 

Grüße

Ohne Rang
26 Beiträge
Martin_ Als Antwort am 10 Nov. 2016 17:10
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Guten Abend, 

muss euch Experten nochmals um Rat fragen. Muss ich Visual Studio auf demselben Server installieren wo auch SharePoint installiert ist oder kann ich es auf einen beliebigen Server installieren und mich dann auf die SharePoint Seite verbinden im Visual Studio drinnen?

 

Grüße

 

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 11 Nov. 2016 08:31
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Klarer Fall von "hängt davon ab" ;-)

Man kann zum einen sog. Full Trust Farm Solutions erstellen. Dazu braucht man einen eigenen Entwicklungsserver mit SharePoint und Visual Studio auf einer Maschine. Man kann dabei das Server Object Model verwenden und damit so gut wie alles machen. Außerdem ist es meiner Meinung nach einfacher. Ich würde es allerdings für neue Entwicklungen nur noch machen, wenn es wirklich unbedingt notwendig ist und das sehe ich hier nicht.

Also bleibt Nummer 2: eine SharePoint App (Add-In). Dabei kann man das Client Object Model verwenden, muß aber nicht. Man kann auch direkt REST ansprechen. Visual Studio kann dann auf einem beliebigen Rechner laufen, Hauptsache es besteht Zugriff auf SharePoint.

Für weitere Recherchen suche mal nach SharePoint Provider-Hosted Apps. Und schaue Dir auch mal das PnP-Projekt an. Da gibt es jede Menge nützliche Erweiterungen und Beispiele.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
26 Beiträge
Martin_ Als Antwort am 11 Nov. 2016 11:43
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Super, vielen Dank für die ausführliche Antwort.