In diesem Blog beschreibe ich, wie man mit Hilfe der BPOS Web Services Datumfelder updaten kann. Dabei wird die Lösung des folgenden Problems vorgestellt:
Beim updaten eines Datumsfeldes wird folgender Error Code zurückgegeben: 0x8102001c,
der auf einen unzulässigen Datums- Zeitwert verweist.
Ausgangspunkt ist ein Silverlight Gantt, das via Web Service ausgelesene Aufgaben anzeigt. Diese können im Panel verschoben werden. Der User entscheidet dann, ob er die Änderungen speichern möchte. Im Prototyp können Start- und Endedatum sowie der Titel zurückgeschrieben werden.
Gantt vor dem Verschieben der SAP Aufgaben
Gantt nach dem Verschieben der SAP Aufgaben
Diese Veränderung kann nun in die Aufgabenliste geschrieben werden. Hier der Quellcode:
Zunächst sehen Sie die Eventhandler des Buttons Änderungen speichern
private void Button_Click(object sender, RoutedEventArgs e)
{
List<Aufgaben> newAufgabenliste = new List<Aufgaben>();
foreach (IGanttNode n in nodes)
{
ExampleGanttNode en = (ExampleGanttNode) n;
newAufgabenliste.Add(ConvertNodeToAufgabe(en));
if (en.ChildNodes != null)
{
foreach (IGanttNode n2 in en.ChildNodes)
{
ExampleGanttNode en2 = (ExampleGanttNode)n2;
newAufgabenliste.Add(ConvertNodeToAufgabe(en2));
}
}
}
UpdateAufgabenliste(newAufgabenliste);
}
Dieser bereitet zunächst eine Aufgabenliste auf, die aus den Knoten der Gantt-Nodes konvertiert wird. Die Knoten sind Observable Objects, d.h. jede visuelle Änderung, also das Verschieben auf der Zeitleiste, wird in die zugrundeliegende Datenstruktur geschrieben.
Der Trick besteht darin, diese Knoten in eine Aufgabenliste zu konvertieren.
private Aufgaben ConvertNodeToAufgabe(ExampleGanttNode node)
{
Aufgaben result = new Aufgaben
{
Title = node.TaskName,
StartDate = node.StartDate,
EndeDate = node.EndDate,
ID = node.ID
};
return result;
}
Der Rückgabewert der Funktion ConvertNodeToAufgabe ist vom Typ Aufgaben, ein C# Typ, der eine BPOS-Aufgabenliste abbildet. Die folgende Grafik zeigt einen Ausschnitt.
Wir konvertieren also alle Knoten des Gantt in eine Aufgabenliste. Diese muss dann in die Aufgabenliste von BPOS zurück geschrieben werden. Das übernimmt die Funktion:
UpdateAufgabenliste(newAufgabenliste);
private void UpdateAufgabenliste(List<Aufgaben> newAufgabenlist)
{
StringBuilder sb = new StringBuilder();
sb.Append(“<Batch OnError=\”Continue\”>”);
int indexer = 1;
foreach(Aufgaben a in newAufgabenlist) {
String dateS = DateTime.Parse(a.StartDate.ToString()).ToString(“yyyy-MM-ddTHH:mm:ssZ”);
String dateE = DateTime.Parse(a.EndeDate.ToString()).ToString(“yyyy-MM-ddTHH:mm:ssZ”);
sb.Append(“<Method ID = \”" + indexer + “\” Cmd=\”Update\”>”);
sb.Append(“<Field Name = \”ID\”>” + a.ID + “</Field>”);
sb.Append(“<Field Name=\”Title\”>” + a.Title + “</Field>”);
sb.Append(“<Field Name=\”StartDate\”>” + dateS + “</Field>”);
sb.Append(“<Field Name=\”DueDate\”>” + dateE + “</Field>”);
sb.Append(“</Method>”);
indexer++;
}
sb.Append(“</Batch>”);
XElement batch = XElement.Parse(sb.ToString());
// MessageBox.Show(batch.ToString());
proxy.UpdateListItemsAsync(ListGUID.Aufgaben, batch);
}
Die entscheidenden Zeilen sind rot hervorgehoben. Die in der Aufgabenliste als DateTime typisierten Start- und Endedaten werden jeweils in einen String gewandelt, der das gezeigte Format besitzt. Mit Hilfe einer StringBuilder Instanz wird eine XML-Struktur gebaut, die als Batch, also als Folge von Befehlen, an den Web Service gesendet wird.
Wir erzeugen dann ein XElement auf der Basis der StringBuilder Instanz.
XElement batch = XElement.Parse(sb.ToString());
Als nächstes wird der asynchrone Web Service von Silverlight aufgerufen. Dabei übergeben wir eine List-GUID und besagtes XElement.
proxy.UpdateListItemsAsync(ListGUID.Aufgaben, batch);
Alle Datumsfelder werden nun anstandslos aktualisiert und in die BPOS-Aufgabenliste geschrieben.
Die folgende Bilder zeigen das gesendete XElement sowie den Response des Web Service.
