Seiten

Herzlich willkommen im technischen Blog der MindBusiness GmbH
In diesem Blog veröffentlichen wir praxisnahes Know-how, neue Erkenntnisse und Erfahrungen zu Microsoft SharePoint- und Office-Themen direkt aus unserer Berater-, Trainer- und Entwickler-Praxis. Hier finden Sie interessante Lösungen und neue Ideen zu den verschiedensten Anforderungen und Problemen. Unseren News-Blog finden Sie unter newsblog.mindbusiness.de/newsblog. Wir wünschen Ihnen viel Spaß beim Lesen und Stöbern und freuen uns auf den Austausch mit Ihnen.

SharePoint ListItems mit Silverlight updaten – was tun bei leeren Felder

Dieser Blog beschreibt, wie man mit einer Silverlight-Anwendung ein BPOS-ListItem updaten kann, das  eventuell leere Felder hat. Das Grundproblem besteht darin, dass man zuerst das Item laden muss, bevor es aktualisiert werden kann. Aus verständlichen Performance-Gründen sendet der Web Service aber nur Felder mit Inhalt.

Diese werden auf Attribute gemappt. Wenn ein Attribut fehlt, weil es im Item keinen Inhalt hat, dann laufen wir auf einen Fehler wenn wir auf das Attribut zugreifen um es in unsere Eingabemaske zu schreiben.

Zwei Lösungsansätze – Attribute hinzufügen oder vor jedem Zugriff testen

Attribute hinzufügen

In der beschriebenen BPOS-Lösung wurde eine interaktive Eingabemaske erstellt, die sowohl zum Anlegen als auch zum Aktualisieren eines Items verwendet wird.

Die zugrundeliegende Tabelle sieht in diesem Beispiel so aus:

image

 

Dabei wird das zu aktualisierende Item über den Namen gesucht, der in einem AutoComplete-Feld eingeben wird.

image

 

Ich habe dabei folgende Abfrage entwickelt, die eine Helpermethode zum erzeugen der Query verwendet.Die Enumeration ClubListen dient dazu, die verschiedenen asynchronen Requests zu identifizieren.

XElement query = XDocument.Parse(this.makeCamelID(this.AutoNamen.Text)).Element("Query");

this.flagListe = ClubListen.MITGLIED_EINFUEGEN;
proxy.GetListItemsAsync(ListenGUID.Mitglieder, null, query, null, null, null, null);

image

Die Methode wird beim Klick auf den Button Einfügen ausgelöst.

 

Die registrierte Callback-Methode sieht dann so aus:

void proxy_GetListItemsCompleted(object sender, GetListItemsCompletedEventArgs e)
        {
          ….. // Code ausgelassen  

       if (flagListe == ClubListen.MITGLIED_EINFUEGEN)
            {
                this.populateMaske(e);

            }

      …… // Code ausgelassen

 

        }

Ich rufe die Helpermethode populateMaske(e) auf, der als Parameter das Ergebnis des asynchronen Request übergeben wird. Und in dieser Methode wird dann das eingangs beschriebene Problem gelöst.

Die Methode ist relativ lang. Deshalb wird sie hier in kleinen Modulen beschrieben.

In einem ersten Schritt sorge ich dafür, dass fehlende Attribute erzeugt und mit einem Standardwert belegt werden. Dazu brauche ich einen String, der alle Attribute, die ich erwarten muss, enthält. Dieser String mappt in gewisser Weise die  Eingabemaske.

String suchString = "ows_Title;ows_FirstName;ows_WorkAddress;ows_WorkZip;ows_WorkCity;ows_HomePhone;";
suchString += "ows_Email;ows_Geburtstag;ows_Abteilung;ows_Posten;ows_Mitglied_seit;ows_ID";

Als nächste erzeuge ich ein XElement, welches das für die Maske relevante Element aus dem XML des asynchronen Requests extrahiert. Dazu muss man natürlich den Aufbau des Response kennen. Dieser wird aber noch an anderer Stelle in einem Blogbeitrag beschrieben werden.

XElement element = e.Result.Elements().First().Elements().First();

In diesem Element finde ich aber nur die Attribute der Felder des Items, die nicht leer sind.

Deshalb müssen wir nun schauen, welche Attribute fehlen.

IEnumerable<XAttribute> attribute = element.Attributes();
String[] myAttribute = new String[attribute.Count()];

            int i = 0;
            foreach (XAttribute attribut in attribute)
            {
                myAttribute[i] = attribut.Name.ToString();
                i++;
            }

            foreach (String s in suchString.Split(‘;’))
            {
                if (!myAttribute.Contains(s))
                {
                    XAttribute x = new XAttribute(s, "");
                    element.Add(x);
                }
            }

Als erstes erzeugen ich  eine iterierbare Attribut-Collection. Deren Anzahl dient zur dynamischen Erzeugen eines String-Arrays, in das ich den Namen der Attribute schreiben.

 

  int i = 0;
            foreach (XAttribute attribut in attribute)
            {
                myAttribute[i] = attribut.Name.ToString();
                i++;
            }

 

Jetzt weis ich, welche Attribute, sprich Felder, übertragen wurden.

Im nächsten Schritt lege ich alle Attribute an, die nicht übertragen wurden, weil die Felder im SharePoint-Item leer waren.

foreach (String s in suchString.Split(‘;’))
           {
               if (!myAttribute.Contains(s))
               {
                   XAttribute x = new XAttribute(s, "");
                   element.Add(x);
               }
           }

Finde ich das Attribut, genauer seinen Namen nicht, weil es nicht im String enthalten ist, dann erzeuge ich das Attribut und füge es dem XElement zu.

Jetzt kann ich alle meine Maskenfelder füllen. Sollten zukünftig weitere Felder hinzukommen, muss ich lediglich den Suchstring erweitern.

Vor jedem Zugriff Testen, ob das Attribute vorhanden ist

Bei diesem Ansatz habe ich ein Array mit allen möglichen Attributen erstellt, die ich in die Eingabemaske schreiben möchten. Ein Ausschnitt des Arrays sieht dann so aus:

            this.mAttribute[1] = "ows_FirstName";
            this.mAttribute[2] = "ows_Title";
            this.mAttribute[3] = "ows_Strasse";
            this.mAttribute[4] = "ows_WorkZip";
            this.mAttribute[5] = "ows_WorkCity";

Beim Befüllen der Maske überprüfe ich vor jedem Zugriff, ob es das Attribut gibt. Wenn ja, schreibe ich seinen Inhalt, Value, in das entsprechende Eingabefeld.

           if (myAttribute.Contains(mAttribute[1])) this.txtName.Text = element.Attribute(mAttribute[1]).Value;
           if (myAttribute.Contains(mAttribute[2])) this.txtNachname.Text = element.Attribute(mAttribute[2]).Value;
           if (myAttribute.Contains(mAttribute[3])) this.txtStrasse.Text = element.Attribute(mAttribute[3]).Value;
           if (myAttribute.Contains(mAttribute[4])) this.txtPLZ.Text = element.Attribute(mAttribute[4]).Value;
           if (myAttribute.Contains(mAttribute[5])) this.txtOrt.Text = element.Attribute(mAttribute[5]).Value;

Bei entsprechendem Aufbau der Eingabemaske kann mit wenig Aufwand die Eingabemaske um weiteren Feldern erweitert werden. Dazu muss dann lediglich das Array erweitert werden.

Hinterlasse eine Antwort

 

 

 

Du kannst diese HTML-Tags benutzen

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">