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.




ItemUpdating Event properties.listItem.Properties problem

Geprüfte Antwort Dieser Beitrag hat 8 Antworten

Ohne Rang
163 Beiträge
Markus Sallmutter erstellt 17 Juli 2012 14:51
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo Community!

Ich wende mich heute an euch mit einem Problem das mich nun schon seit mehreren Stunden beschäftigt, obwohl es mir so simpel scheint.

Ich habe einen EventReceiver, der ItemUpdating und ItemUpdated Events verwendet. Was ich nun machen will ist folgendes: Ich versuche im ItemUpdating einen String mit Informationen, welche ich nacher im ItemUpdated benötige in die properties.listitem.Properties zu speichern, sodass ich sie nach wieder auslesen kann.

Mittels properties.ListItem.Properties.Add("rel", i.ParentList.ID + "." + i.UniqueId); funktioniert das auch, jedoch sind die änderungen im ItemUpdated Event nichtmehr da. Kann mir jemand vielleicht sagen woran das liegen könnte?

Außerdem scheint es bereits einmal funktioniert zu haben, denn ich habe einen Wert in der Property drinstehen, jedoch ist das natürlich nur in einem von vielen Update fällen der richtige...

Bitte helft mir bin für jede Antwort sehr dankbar!

Mfg

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 17 Juli 2012 17:42
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Markus Sallmutter"]Ich versuche im ItemUpdating einen String mit Informationen, welche ich nacher im ItemUpdated benötige[/quote]

Ich mache das immer mit einem generischen Dictionary<int, string>, das als statisch in der EventReceiver-Klasse definiert ist. Als Key verwende ich dabei die ID des ListItems. Im ItemUpdating schaue ich, ob es einen Eintrag gibt und entferne ihn dann wieder, damit beim nächsten Ereignis nicht wieder die selbe Aktion ausgelöst wird.

Achtung: die Zugriffe auf dieses Dictionary müssen synchronisiert werden (mit lock).

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
163 Beiträge
Markus Sallmutter Als Antwort am 18 Juli 2012 07:35
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Danke für deine Antwort Andi!

Ich habe es mit einer statischen Variable bereits zum laufen gebracht jedoch habe ich gelesen, dass eine statische Variable probleme machen könnte wenn mehrere User auf sie zugreifen. Bei mir sind es sehr viele User die diese Variable verwenden würden weshalb ich eine alternative suche.

Kannst du mir bitte genaueres über die lock Methode von der du gesprochen hast sagen? wenn diese die Variable synchronisiert wäre das ja für mein problem perfekt, jedoch weiß ich nicht genau ob jeder user der den sharepoint gerade verwendet einen eigenen Thread für den EventReceiver hat...

Mfg

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 18 Juli 2012 08:44
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Genau dazu ist das lock da...

Definiere eine weitere statische Variable:
static object syncRoot = new object();

Immer wenn Du auf das Dictionary zugreifen möchtest, baust Du ein lock ein:
lock (syncRoot) {
  // hier kannst Du synchronisiert auf statische Elemente zugreifen
}

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
163 Beiträge
Markus Sallmutter Als Antwort am 18 Juli 2012 08:48
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

ok soweit sogut... Jetzt noch eine letzte Frage:

Wenn ich im ItemUpdating lock(syncRoot) mache und dann meine Variable fülle, ist dann sichergestellt, dass diese nicht von einem anderen User geändert wird bis ich im ItemUpdated bin und sie auslese? das lock hält ja nur bis zur } denke ich mal da ich keine funktion zum wieder freigeben des locks wie es sie in java gibt gefunden habe...

Achja nochwas^^ kann ich nicht direkt auf die objektvariable in der mein wert steht das lock ausführen?

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 18 Juli 2012 09:02
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

lock stellt sicher, daß nicht zweu Threads auf ein und dasselbe Element zugreifen. Man sollte es wirklich nur die kürzest mögliche Zeitspanne benutzen.

Ich denke aber, Dein Problem liegt ganz woanders: Du kannst Deinen Wert nicht einfach in einem String ablegen, weil mehrere Events für unterschiedliche Elemente gleichzeitig ausgelöst werden können. Schau Dir deshalb mein Beispiel mit dem Dictionary nochmal an. Dabei wird jeweils ein Wert für ein ganz bestimmtes Element abgelegt.

[quote user="Markus Sallmutter"]kann ich nicht direkt auf die objektvariable in der mein wert steht das lock ausführen?[/quote]

Nein, man braucht ein separates Synchronisierungsobjekt, das ansonsten keine Funktion haben muß.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
163 Beiträge
Markus Sallmutter Als Antwort am 18 Juli 2012 09:21
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo Andi!

Danke für deine Antwort du hast mir sehr geholfen.

Wenn ich alles richtig verstanden habe müsste es jetzt funktionieren, tut es aba ich bin ja nur 1 user der testet ;)

Ich habe es jetzt mit dem Dictionary gelöst wie du gesagt hast und setzen den wert im ItemUpdating folgendermaßen:

lock (syncRoot)
{
   oldRelItemInfo.Add(properties.ListItem.ID,i.ParentList.ID.ToString()+"."+ i.UniqueId.ToString());
}
Danach wird gleich der ItemUpdated Event getriggert in dem gleich zu beginn die Info ausgelesen wird:
lock (syncRoot)
{
    string[] relBuffer = oldRelItemInfo[item.ID].Split('.');
    Guid g = new Guid(relBuffer[0]);
    Guid ig = new Guid(relBuffer[1]);
    oldRelatedItem = item.Web.Lists[g].Items[ig];
    oldRelItemInfo.Remove(item.ID);
 }

Sollten dir noch irgendwelche Fehler oder Probleme daran auffallen sag bitte bescheid
Danke nochmal für deine Hilfe!!

Mfg
Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 18 Juli 2012 09:46
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich würde innerhalb des lock wirklich nur das gespeicherte Element holen und entfernen. Nicht vergessen zu prüfen, ob überhaupt etwas gespeichert wurde!. Dein Code schmeißt sonst Fehler.

Und noch ein "Schönheitsfehler": Du speicherst da einen zusammengesetzten String. Ich würde eine ganz einfache eigene Klasse mit passenden Properties erstellen und diese speichern. Du hast dann einen typsicheren Zugriff auf alles notwendige und man kann es bei Bedarf später ganz leicht erweitern.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
163 Beiträge
Markus Sallmutter Als Antwort am 18 Juli 2012 10:06
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Danke für die Tipps!

Das mit der Klasse find ich ne sehr gute Idee und habs auch schon implementiert. Außerdem hab ich im lock jetzt wirklich nur mehr das was das zu synchronisierende Item betrifft.

Was die Fehler angeht brauche ich nicht prüfen weil um das lock ein Try-Catch block ist und wenn etwas schief geht ist das item null und später im code überprüfe ich ob es null ist und reagiere darauf.

Danke für die große Hilfe hätte ohne dir wahrscheinlich noch einige Stunden mehr investieren müssen :D