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: Zugriff auf Lookup Field in Before Events

Unbeantwortet Dieser Beitrag hat 12 Antworten

Ohne Rang
32 Beiträge
Exes Forum erstellt 31 Mai 2011 14:20
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo,

 

ich möchte ein Lookup Field innerhalb eines Event Receivers auslesen und in einem andern Feld der gleichen Liste speichern. Dieses ist ein normales Textfeld. Ich hänge jedoch an dem Auslesen des LookupFields, da hier nur die ID ausgegeben wird.

Ich habe im Netz jetzt folgende Lösung gefunden, welche jedoch für Sharepoint 2010 geschrieben ist:

SPFieldLookup lookup = (SPFieldLookup)properties.List.Fields["Projektname"];
Int32 singlelookupItemID = Convert.ToInt32(properties.AfterProperties["Projektname"]);
string Projektname = properties.Web.Lists[new Guid(lookup.LookupList)].GetItemById(singlelookupItemID)

Properties.Web.Lists geht in Sharepoint 2007 nicht. Gibt es da irgendeine Möglichkeit das anders zu realisieren?

 

Schöne Grüße!

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 31 Mai 2011 15:05
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Das Prinzip ist doch ganz einfach: aus den AfterProperties bekommst Du die ID des nachgeschlagenen Elements. Dieses Element holst Du Dir aus der entsprechenden Liste und hast damit auch den Textwert.

using (SPWeb web = properties.OpenWeb()) {
SPFieldLookup lookupField = (SPFieldLookup)properties.List.Fields["Projektname"];
int lookupId = Convert.ToInt32(properties.AfterProperties["Projektname"]);
SPList lookupList = web.Lists[lookupField.LookupList];
SPListItem lookupItem = lookupList.GetItemById(lookupId);
string displayText = lookupItem[lookupField.LookupField] as string;
}

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
32 Beiträge
Exes Forum Als Antwort am 31 Mai 2011 15:54
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Danke! Ich habs auf einem etwas anderen Weg hinbekommen.

SPFieldLookupValueCollection flvc = new SPFieldLookupValueCollection(item["Teilnehmer"].ToString());
            foreach (SPFieldLookupValue flv in flvc)
            {
                id = flv.LookupId.ToString(); //enthält die Id des verknüpften ListItems
                value += flv.LookupValue; //enthält den Wert des verknüpften ListItems
               
            }

 

Ist noch nicht ganz optimiert, da die Strings noch nicht sauber angefügt werden aber das ist ja nicht mehr das Problem.

Das GROßE PROBLEM ist jedoch, dass der Wert in dem Feld in das die Strings kopiert werden soll immer erst nach einem neuen "edit" auf der Liste aktualisiert werden. Ich vermute, dass ich item.Update() aufrufen muss, jedoch bekomme ich immer, sobald ich dies Aufrufe einen "Save Conflict".

 

Gruß

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 31 Mai 2011 16:07
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Warum sagst Du nicht gleich, daß es sich um ein Lookup mit Mehrfachauswahl handelt? ;-)

Du greifst auf den Wert hier per properties.ListItem zu. Je nach Ereignis und Listentyp sind das aber die alten Werte. Ebenfalls je nach Ereignis und Listentyp findet man die neuen, aktuellen Werte in properties.AfterProperties.

Zu Deinem Problem mit dem "Save Conflict" solltest Du Dich zum Unterschied zwischen den *ing und *ed Ereignissen schlau machen. Die *ing-Ereignisse sind synchron, die *ed-Ereignisse sind asynchron.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
32 Beiträge
Exes Forum Als Antwort am 31 Mai 2011 16:13
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Stimmt das hatte ich vergessen :) Sorry.

Danke für den Hinweis mit dem *ing und *ed Ereignissen. Ich habe schon beide ausprobiert (updated und updating) und bei beiden das gleiche Problem gehabt. Werde mich aber jetzt nochmal genauer damit befassen. Es ist doch aber kein Problem ein Updating in ein Updated zu ändern, indem ich die Overridemethode umschreibe und den EventReceiverType anpasse?

public override void ItemUpdating(SPItemEventProperties properties)

spListSeminarInstanzen.EventReceivers.Add(SPEventReceiverType.ItemUpdated, "TeilnehmerEvent, V...

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 31 Mai 2011 16:30
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Exes Forum"]Es ist doch aber kein Problem ein Updating in ein Updated zu ändern[/quote]

Doch! Je nachdem, was Du dort machen möchtest, kann das einen riesigen Unterschied machen. Z.B. wenn Du versuchst aus dem EventReceiver heraus genau dieses Listenelement zu ändern.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
32 Beiträge
Exes Forum Als Antwort am 7 Jun 2011 13:12
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Hallo,

bin leider krankheitsbedingt ein paar Tage ausgefallen. Ich drehe mich hier irgendwie im Kreis : / Der Code ist folgender:

namespace TeilnehmerUpdated
{
    public class Copy : SPItemEventReceiver

    {
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            this.DisableEventFiring();
            String value = "";
            String id = "";
           

            SPListItem item = properties.ListItem;
          
            SPFieldLookupValueCollection flvc = new SPFieldLookupValueCollection(item["Teilnehmer"].ToString());
            foreach (SPFieldLookupValue flv in flvc)
            {
                id = flv.LookupId.ToString(); //enthält die Id des verknüpften ListItems
                value += flv.LookupValue + ";"; //enthält den Wert des verknüpften ListItems

            }
            properties.ListItem["TeilnehmerTest"] = value;

            properties.ListItem.Update();
            this.DisableEventFiring();
        }
    }
}

 

Ich bekomme einfach nicht realisiert, dass nach einem Listenedit das Feld TeilnehmerTest sofort geupdated wird. Die neuen Werte, welche beim Listenedit eingefügt wurden, werden immer erst nach einem weiteren Listenedit eingetragen. Woran liegt das?

Ich habe es jetzt mit ItemUpdated, ItemUpdating und auch mit Afterproperties und wie oben versucht.

 

Viele Grüße

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 7 Jun 2011 13:26
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Exes Forum"]Ich bekomme einfach nicht realisiert, dass nach einem Listenedit das Feld TeilnehmerTest sofort geupdated wird. Die neuen Werte, welche beim Listenedit eingefügt wurden, werden immer erst nach einem weiteren Listenedit eingetragen. Woran liegt das?[/quote]

wenn Du Deinen Code debuggst, wirst Du sehen, daß es nur ein Mißverständnis ist. Das Feld wird bereits beim erstenmal geupdated, aber es wird nicht sofort angezeigt. Die *ed-Events werden immer asynchron nach dem eigentlichen Update ausgeführt. Die Browseransicht wird also aktualisiert und erst dann wird Dein EventReceiver ausgeführt. Dieses Verhalten ist so gewollt und kann auch nicht geändert werden.

Für das, was Du erreichen möchtest, wäre ItemUpdating besser geeignet. Dort greifst Du dann nicht auf properties.ListItem, sondern auf properties.AfterProperties zu. Deinen zusammengesetzten String "value" schreibst Du ebenfalls in die properties.AfterProperties. Ein properties.ListItem.Update() brauchst Du nicht. Und lasse das DisableEventFiring/EnableEventFiring weg!

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
32 Beiträge
Exes Forum Als Antwort am 7 Jun 2011 13:34
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Dann sieht mein Code wie folgt aus:

 

namespace TeilnehmerEvent
{
    public class Copy : SPItemEventReceiver
    {
        public override void ItemUpdating(SPItemEventProperties properties)
       
        {
            String value = "";
            String id = "";
                      
            SPListItem item = properties.ListItem;
                  

            SPFieldLookupValueCollection flvc = new SPFieldLookupValueCollection(item["Teilnehmer"].ToString());
            foreach (SPFieldLookupValue flv in flvc)
            {
                id = flv.LookupId.ToString(); //enthält die Id des verknüpften ListItems
                value += flv.LookupValue+";"; //enthält den Wert des verknüpften ListItems
               
            }
           
            properties.AfterProperties["TeilnehmerTest"] = value;

 

Zumindest habe ich es so verstanden. Allerdings habe ich auf diesem Weg immer noch das gleiche Problem. Ich muss immer noch einmal über das Listedit in die Liste gehen und dann stehen die richtigen Werte erst in dem Feld. Eigentlich würde mir ja schon eine Option helfen, die die Liste einfach nochmal aktualisiert?!

 

Gruß!

Ohne Rang
32 Beiträge
Exes Forum Als Antwort am 7 Jun 2011 13:41
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich vermute, dass das Problem darin liegt, dass ich das LookupField in der Liste bearbeite, indem ich darüber Teilnehmer hinzufüge bzw. lösche und gleichzeitig das "TeilnehmerTest" Field in der Liste mit dem neuen Inhalt des Lookups füllen möchte. Somit füllt er das "TeilnehmerTest" Feld immer mit den alten Daten, da die neuen ja erst beim Edit eingegeben werden?! Ich hoffe man versteht ungefähr was ich meine ;)

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 7 Jun 2011 13:52
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ich habe doch oben geschrieben, daß Du nicht über properties.ListItem gehen sollst. Die neuen werte stehen in properties.AfterProperties!

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
32 Beiträge
Exes Forum Als Antwort am 7 Jun 2011 14:10
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ah! Bin langsam völlig durcheinander :D

SPFieldLookupValueCollection flvc = new SPFieldLookupValueCollection(properties.AfterProperties["Teilnehmer"].ToString());
            foreach (SPFieldLookupValue flv in flvc)
            {
                id = flv.LookupId.ToString(); //enthält die Id des verknüpften ListItems
                value += flv.LookupValue+";"; //enthält den Wert des verknüpften ListItems
               
            }
           
            properties.AfterProperties["TeilnehmerTest"] = value;

 

Jetzt besteht nur noch das Problem, dass er mir nach einer Änderung nur die Semikolons anzeigt und nach drücken von F5 dann den kompletten String mit den Namen.

 

 

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 7 Jun 2011 14:30
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Die Änderungen, die auf diese Art gemacht werden, sind immer zusammen mit den vom Benutzer gemachten Änderungen verfügbar. Wenn Du dabei ein Problem mit der Anzeige im Browser hast, dann wird es wohl ein clientseitiges Caching-Problem sein.

Zu der Sache mit den fehlenden Strings: manchmal hat man in den AfterProperties bei Lookups nur die ID (LookupId), aber nicht den angezeigten Text (LookupValue). Wann genau das so ist, kann ich aus dem Stehgreif gerade nicht sagen. Das mußt Du selbst im Debugger herausfinden. Du kannst Dir in so einem Fall behelfen, indem Du Dir die ListItems aus den Nachschlagelisten holst.

Viele Grüße
Andi
af @ evocom de
Blog