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.




Ereignishandler

Unbeantwortet Dieser Beitrag hat 9 Antworten

Ohne Rang
150 Beiträge
CptGreenwood erstellt 31 Juli 2014 13:40
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo,

ich möchte einen Ereignishandler einsetzen, um zwei Felder in einer Liste zu überprüfen, wenn ein neues Element hinzugefügt wird und das Hinzufügen ggf. abbrechen, wenn das Element nicht brauchbar ist. Dazu habe ich folgende Funktion implementiert:

 public override void ItemAdding(SPItemEventProperties properties)
{
 
string t2 = properties.ListItem["Einzeltätigkeit"].ToString();
 
string t1 = properties.ListItem["Tätigkeitsfeld"].ToString();

    if (t2.Substring(0, 2) != t1.Substring(0, 2))
  {
    properties.Cancel =
true;
    properties.ErrorMessage =
"Tätigkeit passt nicht zum Tätigkeitsfeld!";
  }

  base.ItemAdding(properties);
}

Mein Problem ist, dass die Funktion bei Speichern eines neuen Elementes zwar aufgerufen wird, das Übergabeobjekt "properties" allerdings null ist, ich also nicht an das ListItem mit seinen Feldinhalten komme.

Was mache ich falsch?

Viele Grüße,
Ralf

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 31 Juli 2014 14:18
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

In ItemAdding gibt es noch kein ListItem. es wird erst danach angelegt und Du möchtest genau das ja abbrechen können ;-)

Benutze einfach properties.AfterProperties["Feldname"]

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
150 Beiträge
CptGreenwood Als Antwort am 31 Juli 2014 14:38
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ah, ok. Für das Abbrechen selbst und die Fehlermeldung benutze ich aber wie gehabt "properties"?

Ohne Rang
150 Beiträge
CptGreenwood Als Antwort am 31 Juli 2014 14:45
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Habe es gerade ausprobiert. Bei der Zeile

string

 

 

 

t2 = properties.AfterProperties["Einzeltätigkeit"].ToString();

bekomme ich einer Nullpointer-Exception. (Macht ja auch irgendwie Sinn, wenn "properties" null ist, gibt es "properties.AfterProperties" doch auch nicht)

Muss mein Code vor oder nach dem Aufruf der Basisklassenfunktion stehen?
Benutze ich den richtigen Handler? Ich möchte, dass der Datensatz gar nicht angelegt wird, wenn der Vergleich in "if" nicht true ergibt.

Ohne Rang
150 Beiträge
CptGreenwood Als Antwort am 31 Juli 2014 15:22
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hab zwischenzeitlich noch ein wenig geforscht. Im Handler "ItemAdding" ist "properties" wohl immer null, d.h. ich kann darüber auf meine Feldwerte nicht zugreifen. Im Handler "ItemAdded" kann ich das. Ich habe meine Zeichenketten herausgezogen und verglichen, alles super. ABER: Wenn meine Bedingungen nicht erfüllt sind, kann ich nicht verhindern, dass das Item angelegt wird. Er ist ja schon da...

Wie kann ich am Ende das Anlegen eines für mich ungültigen Items wirklich verhindern? Hilfe... :-(

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 31 Juli 2014 16:53
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

properties ist niemals null, da mußt Du Dich verguckt haben.

ItemAdding ist genau die richtige Stelle für das, was Du vorhast und Du kannst die Neuanlage mit properties.ErrorMessage usw. abbrechen.

Du mußt nur beim Zugriff auf die AfterProperties aufpassen. Mache es z.B. so:

string value = properties.AfterProperties["Fieldname"] as string;
if (string.IsNullOrEmpty(value)) {
  // value ist leer, d.h. vom Benutzer wurde nichts eingegeben
}

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
150 Beiträge
CptGreenwood Als Antwort am 31 Juli 2014 17:24
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Da wird der Hund in der Pfanne verrückt. Ja, "properties" selbst ist nicht null, sondern nur "properties.ListItem". Wie du geschrieben hast habe ich "properties.AfterProperties["Einzeltätigkeit"] verwendet, und es gab eine Null-Pointer-Exception. Ich habe im Debugmodus mal ein wenig in "properties.Afterproperties" herumgebohrt und in den nicht öffentlichen Membern sowohl Feldnamen, als auch meine Daten gefunden. Nur stand dort für den fraglichen Feldnamen anstatt "Einzeltätigkeit" hier "Einzelt_x00e4_tigkeit", da gibt es wohl ein Problem mit den Umlauten, seufz.

Mit "properties.AfterProperties["Einzelt_x00e4_tigkeit"]" kann ich mir die Zeichenkette nun tatsächlich raus holen.

Aber es wäre zu schön, wenn ich nicht noch ein Problem hätte: Da die beiden Felder Auswahlfelder sind, erhalte ich als Zeichenkette nur die Nummer des Eintrags der Auswahlliste und kann nicht die eigentlichen Texte vergleichen. Ist es möglich auch an die Zeichenkette zu kommen?

Ohne Rang
150 Beiträge
CptGreenwood Als Antwort am 1 Aug. 2014 08:44
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Inzwischen habe ich es geschafft, an beide Zeichenketten zu kommen, sie zu vergleichen und bei Ungültigkeit eine Fehlermeldung anzuzeigen und das Listenelement nicht zu speichern. Das sind immerhin schon 95% von schön.

Das einzige, was mir daran nicht gefällt ist, dass die Fehlermeldung auf einer riesigen, gelben "Server-Error"-Seite angezeigt wird, die den Anwender erstmal sehr erschreckt. Auch gibt es darin nicht diesen praktischen Link "Zurück zu Website", so dass der Anwender entweder im Browser den Zurückbutton betätigen muss oder verzweifelt anruft.
Überall, wo man im Netz etwas über den Abbruch eines Eventhandlers mit "properties.Errormessage", "properties.Status" und "properties.Cancel" liest, sieht man einen Screenshot von einem netten, kleinen Fehlermeldungsfenster (ähnlich Messagebox) mit einem Zurück-Link. Muss ich dafür noch etwas konfigurieren? Habe noch nichts gefunden...

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 3 Aug. 2014 12:37
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Zum Problem mit den Feldnamen:

beim Zugriff über SPListItem["Fieldname"] kann man den internen oder den sichtbaren Namen verwenden. Beim Zugriff über AfterProperties["Fieldname"] funktioniert nur der interne Name.

Wenn man die Spalten über ein eigenes Feature anlegt, kann man ja problemlos für "schöne" interne Namen sorgen. Wenn man Spalten über den Browser anlegt, empfehle ich immer bei der Neuanlage einen "schönen" Namen zu verwenden (Einzeltaetigkeit) und dann die Spalte umzubennen. Beim Umbenennen bleibt der interne Name erhalten.

Zum Problem mit der Fehlermeldung:

in 2010 geht das leider nicht anders. Immer, wenn man einen EventReceiver abbricht, sieht der Benutzer die unschöne Fehlerseite. Wenn er aber einfach im Browser auf "Zurück" klickt, kommt er wieder aud ei Eingabeseite und kann seine fehlerhaften Eingaben korrigieren. Das Einzige, was Du machen kannst, ist den Benutzer in der Meldung darauf hinweisen: "Sie haben etwas falsch gemacht. Klicken Sie auf Zurück um Ihre Eingaben zu korrigieren."

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
150 Beiträge
CptGreenwood Als Antwort am 4 Aug. 2014 09:20
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Alles geklärt. Vielen Dank!