locked
Weiterverarbeitung von Daten, die von einem WEB-Service zurück gegeben werden RRS feed

  • Frage

  • Hallo,

    wir haben einen WEB-Service, der Daten in der Struktur

    Errocode          string
    Errormessage   string
    Daten              query

    zurück gibt. Im Debugger habe ich im Completed Event auch Zugriff auf alle Daten. Nachfolgend ein Ausschnitt von e.

    -  e {Cobra_3.Cobra.getUserDataCompletedEventArgs} Cobra_3.Cobra.getUserDataCompletedEventArgs
    +  base {Cobra_3.Cobra.getUserDataCompletedEventArgs} System.ComponentModel.AsyncCompletedEventArgs {Cobra_3.Cobra.getUserDataCompletedEventArgs}
    -  Result {Cobra_3.Cobra.ResultTypeQuery} Cobra_3.Cobra.ResultTypeQuery
        ErrorCode 0.0 double?
        ErrorCodeField 0.0 double?
        ErrorMsg "" string
        ErrorMsgField "" string
        PropertyChanged null System.ComponentModel.PropertyChangedEventHandler
          -  result {Cobra_3.Cobra.DocumentQueryBean} Cobra_3.Cobra.DocumentQueryBean
              -  columnList Count = 3 Cobra_3.Cobra.ArrayOf_xsd_string
              [0] "KENNUNG" string
              [1] "ANREDE" string
              [2] "NAME" string
          +  Rohdatenansicht  
      +  columnListField Count =3 Cobra_3.Cobra.ArrayOf_xsd_string
      -  data Count = 1 Cobra_3.Cobra.ArrayOfArrayOf_xsd_anyType
      -  [0] Count = 3 Cobra_3.Cobra.ArrayOf_xsd_anyType
              [0] "admin" object {string}
              [1] "Herr" object {string}
              [2] "Administrator" object {string}
      +  Rohdatenansicht  
    +  Rohdatenansicht  
    +  dataField Count = 1 Cobra_3.Cobra.ArrayOfArrayOf_xsd_anyType
      PropertyChanged null System.ComponentModel.PropertyChangedEventHandler
    +  resultField {Cobra_3.Cobra.DocumentQueryBean} Cobra_3.Cobra.DocumentQueryBean
    +  results {object[1]} object[]

     

    Jetzt habe ich das Problem, wie ich diese Daten in Silverlight weiter nutzen kann. Bei WPF konnte ich ja ein DTable Object erstellen, die Columns und data druchlaufen und damit DTable füllen.

    Beim Versuch, mit ObservableCollection zu arbeiten bekomme ich immer die Fehlermelsung, dass eine Abbildung nicht möglich wäre. Wobei mir nicht ganz klar ist, warum ich noch einmal eine neue Collection erstellen muss. Laut Definition wird doch der Auflistungstyp des Web-Services bereits als ObservableCollection definiert.

     

    Kann mir irgend jemand mit Tips weiterhelfen. Bei der Internet-Recherche bin ich inzwischen immer wieder auf die gleichen Seiten gestoßen ohne dassich recht weiter gekommen bin.

     

    Gruß

     

    Thomas

     


    Thomas Bach
    Donnerstag, 28. Juli 2011 15:56

Antworten

  • Wenn der Webservice immer die gleichen Columns zurückgibt, dann kannst du diese im DataGrid fest definieren.
    Jetzt baust du dir wie in dem 1. Link eine Daten Klasse mit den entsprechenen Columns, die auch im DataGrid definiert wird sind.
    Danach musst du das Result durchlaufen und jeweils eine Daten Klasse mit den Werten erzeugen und das ganze in eine ObservableCollection speichern.
    Diese kannst du im Anschluss an das DataGrid binden.

    Hier ein einfaches Beispiel:

        private ObservableCollection<Data> _dataList = new ObservableCollection<Data>();
    
        private void _Completed(object sender, object e)
        {
          foreach (var row in e.Result.result.data)
          {
            var data = new Data() { FirstName=row["FirstName"], Age=row["Age"], Available=row["Available"], LastName=row{"LastName"] };
    
            _dataList.Add(data);
          }
    
          DataGrid.ItemsSource = _dataList;
        }
    

      public class Data
      {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public bool Available { get; set; }
      }
    
    

     

     

    • Als Antwort markiert Thomas Bach Freitag, 29. Juli 2011 14:02
    Freitag, 29. Juli 2011 08:14
    Beantworter
  • >>Sorry, war nicht so gemeint, als ob das Beispiel keinen Sinn machen würde.
    Kein Ding, war auch nicht so gemeint, hätte das ! auch weglassen können (-;


    >>Habe ich irgendeine Möglichkeit, die Felder in der row, die null als Inhalt haben, mit z.B. einem leeren String zu ersetzen oder wie könnte ich das lösen?
    Das könntest du z.B. so machen:

            var uData = new UserData();
    
            if (row.ElementAt(col.IndexOf("KENNUNG")) == null)
            {
              uData.Kennung = string.Empty;
            }
            else
            {
              uData.Kennung = row.ElementAt(col.IndexOf("KENNUNG")).ToString();
            }
            //Weiter Felder implementieren...
    


    • Als Antwort markiert Thomas Bach Freitag, 29. Juli 2011 14:02
    Freitag, 29. Juli 2011 13:18
    Beantworter

Alle Antworten

  • Schau mal im e Object des Completed Events.
    Dort gibt es ein Result Property.
    Das sind im normalfall deine Daten die vom Webservice zurückkommen...

    Zur weiteren Vorgehensweise, poste doch mal den Code des Completed Events und den Typ des Result Properties.

     

     

    Freitag, 29. Juli 2011 06:41
    Beantworter
  • Hallo Marco,

    danke für die Antwort. An das Result komme ich ja dran. Das Problem ist für mich, dass es ja ein komplexer Datentyp ist. D.h. ich habe e.Result als Typ Query. Darunter dann Errormessage und Errorcode als String. Die bekomme ich auch einwandfrei.

    Dann gibt es aber e.Result.result als DocumentQueryBean. Dadrin stecken dann die Rückgabe der Query. e,Result.result.ColumnList und e.Result.result.data.

     

    Und da hört es momentan bei mir auf. Zum Thema QueryBean ist ja nicht allzu viel zu finden und ich finde einfach keine Möglichkeit, dieses e.Result.result sinnvoll weiter zu verarbeiten.

     

    Gruß

    Thomas


    Thomas Bach
    Freitag, 29. Juli 2011 07:24
  • Ich kenn mich jetzt nicht mit QueryBean aus. Aber ich denke du müsstest dir eine eigenes "DataTable" Objekt erstellen, in dem du die DocumentQueryBean Columns und deren Werte speicherst. Dieses Objekt kannst du dann an DataGrid binden.

    Evtl. helfen dir folgende Links weiter:

    http://blogs.msdn.com/b/scmorris/archive/2008/03/21/using-the-silverlight-datagrid.aspx
    http://slbindabledatagrid.codeplex.com/

     



    Freitag, 29. Juli 2011 07:36
    Beantworter
  • Danke für die Hinweise. Über die Seiten bin ich auch schon gestolpert.

    Wenn ich es richtig verstehe haben all diese Lösungen aber den Nachteil, dass dann z.b. nicht mehr alle Features des Datagrids genutzt werden können.

    Ich wollte eigentlich die Datenrückgabe an eine ObservableCollection überführen. Da hakt es bei mir wegend mangelnden Wissens aber noch mit der Umsetzung

     

    Gruß

    Thomas


    Thomas Bach
    Freitag, 29. Juli 2011 07:48
  • Wenn der Webservice immer die gleichen Columns zurückgibt, dann kannst du diese im DataGrid fest definieren.
    Jetzt baust du dir wie in dem 1. Link eine Daten Klasse mit den entsprechenen Columns, die auch im DataGrid definiert wird sind.
    Danach musst du das Result durchlaufen und jeweils eine Daten Klasse mit den Werten erzeugen und das ganze in eine ObservableCollection speichern.
    Diese kannst du im Anschluss an das DataGrid binden.

    Hier ein einfaches Beispiel:

        private ObservableCollection<Data> _dataList = new ObservableCollection<Data>();
    
        private void _Completed(object sender, object e)
        {
          foreach (var row in e.Result.result.data)
          {
            var data = new Data() { FirstName=row["FirstName"], Age=row["Age"], Available=row["Available"], LastName=row{"LastName"] };
    
            _dataList.Add(data);
          }
    
          DataGrid.ItemsSource = _dataList;
        }
    

      public class Data
      {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public bool Available { get; set; }
      }
    
    

     

     

    • Als Antwort markiert Thomas Bach Freitag, 29. Juli 2011 14:02
    Freitag, 29. Juli 2011 08:14
    Beantworter
  • Hallo Marco,
    nochmals danke. Mit dem Beispiel direkt hat es nicht geklappt. Der Ausdruck row["xxx"] liefert mir einen Fehler.
    Ich habe das jetzt von der Syntax her so:
     
     private void wsCobra_GetUserDataCompleted(object sender, Cobra.getUserDataCompletedEventArgs e)
        {
          
          
    
          var col = e.Result.result.columnList;
    
          if (e.Error != null)
          {
            MessageBox.Show(e.Error.ToString());
          }
    
            
          else
          {
            foreach (var row in e.Result.result.data)
            {
              
              var uData = new UserData()
              {
                Kennung = row.ElementAt(col.IndexOf("KENNUNG")).ToString(),
                Anrede = row.ElementAt(col.IndexOf("ANREDE")).ToString(),
                Name = row.ElementAt(col.IndexOf("NAME")).ToString(),
                Vorname = row.ElementAt(col.IndexOf("VORNAME")).ToString()
              };
            }
            
             
          }
    
        }
    
    In der Schnellüberwachung bekomme ich mit der Syntax den Feldeintrag richtig angezeigt. Lasse ich aber das Programm im Debuger laufen, dann
    erhalte ich die Fehlermeldung:
    System.NullReferenceException wurde nicht von Benutzercode behandelt.<br/>  Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.<br/>  StackTrace:<br/>       bei Cobra_3.MainPage.wsCobra_GetUserDataCompleted(Object sender, getUserDataCompletedEventArgs e)<br/>       bei Cobra_3.Cobra.CobraClient.OngetUserDataCompleted(Object state)<br/>  InnerException: <br/>
    
     

    Thomas Bach
    Freitag, 29. Juli 2011 12:00
  • >>Mit dem Beispiel direkt hat es nicht geklappt. Der Ausdruck row["xxx"] liefert mir einen Fehler.
    Das war auch nur ein Beispiel von mir, da ich nicht weiß wie das Data Objekt aufgebaut ist!

    >>In der Schnellüberwachung bekomme ich mit der Syntax den Feldeintrag richtig angezeigt. Lasse ich aber das Programm im Debuger laufen, dann
    >>erhalte ich die Fehlermeldung:
    Du musst mal einen Breakpoint in der ...Completed Methode setzen und dann genau nachschauen, was für ein Objekt "e.Result.result.data" ist.
    Außerdem solltest du, bevor du die Eigenschaft .data mit der foreach Schleife durchläufst auf null überprüfen.

     

    Freitag, 29. Juli 2011 12:24
    Beantworter
  • Sorry, war nicht so gemeint, als ob das Beispiel keinen Sinn machen würde.

    Dein Tip war goldrichtig. Ich hatte Felder mit null in den data. Von Coldfuiosn her sind wir es halt gewohnt, dass sich das System daran nicht stört.

    Wie Du an den Fragen merkst, bin ich erst Einsteiger in c# und .net. 4 Bücher auf dem Schreibtisch, aber die wollen erst einmal gelesen sein.

    Daher noch ein Hilferuf: Habe ich irgendeine Möglichkeit, die Felder in der row, die null als Inhalt haben, mit z.B. einem leeren String zu ersetzen oder wie könnte ich das lösen?

    Danke

    Thomas


    Thomas Bach
    Freitag, 29. Juli 2011 13:02
  • >>Sorry, war nicht so gemeint, als ob das Beispiel keinen Sinn machen würde.
    Kein Ding, war auch nicht so gemeint, hätte das ! auch weglassen können (-;


    >>Habe ich irgendeine Möglichkeit, die Felder in der row, die null als Inhalt haben, mit z.B. einem leeren String zu ersetzen oder wie könnte ich das lösen?
    Das könntest du z.B. so machen:

            var uData = new UserData();
    
            if (row.ElementAt(col.IndexOf("KENNUNG")) == null)
            {
              uData.Kennung = string.Empty;
            }
            else
            {
              uData.Kennung = row.ElementAt(col.IndexOf("KENNUNG")).ToString();
            }
            //Weiter Felder implementieren...
    


    • Als Antwort markiert Thomas Bach Freitag, 29. Juli 2011 14:02
    Freitag, 29. Juli 2011 13:18
    Beantworter
  • Hallo Marco,

    nochmals vielen Dank. Das klappt jetzt so.

    Rein bauchmäßig habe ich das Gefühl, dass man das aber noch irgendwie vereinfachen können müsste. Ich habe ja eigentlich in dem WEB-Service sämtliche Informationen darüber, wie die Daten aufgebaut sind. Irgendwie nervt das, wenn man dann noch einmal die ganzen Strukturen neu definieren muss.

    Aber vielleicht finde ich ja doch noch irgendwelche Hinweise.

    Ich bin jedenfalls heilfroh, dass das jetzt klappt. Du hast mir das Wochenende gerettet :-)

    Gruß

    Thomas


    Thomas Bach
    Freitag, 29. Juli 2011 14:02
  • Freitag, 29. Juli 2011 14:26
    Beantworter
  • Hallo Marco,

    die Infos in den Links gehen momentan etwas über meinen Horizont. Ich denke aber, dass z.B. da WSDL-Tool ja auch aufgerufen wird, wenn ich den Service direkt aus VS2010 generiere.

    Ich bleibe jetzt erst einmal bei der Lösung bei der Du mir so klasse geholfen hast.

    Gruß

    Thomas

     


    Thomas Bach
    Freitag, 29. Juli 2011 15:20