2016-05-02 23 views
-1

Ich habe einen Datenvertrag implementiert, der erfolgreich vom WCF-Testclient deserialisiert wurde. Nun, wie kann ich dies in einem benutzerdefinierten Client tun, den ich gemacht habe?Wie deseriert der WCF-Testclient den Datenvertrag? Wie man eine Liste von DataContract-Objekten deserialisiert

Der Vertrag, den ich habe, ist dies:

public List<StageContract> getAllStages() 
    { 
      return (new StageController()) 
      .getAllStages() 
      .Values 
      .Select(s => new StageContract(s)) 
      .ToList(); 
    } 

In der Client-Seite:

[ServiceContract] 
[ServiceKnownType(typeof(List<StageContract>))] 
public interface IUserService 
{ 
    [OperationContract] 
    void CreateUser(string name, string pwd, bool admin); 

    [OperationContract] 
    bool LogInUser(string name, string pwd); 

    [OperationContract] 
    List<StageContract> getAllStages(); 


[DataContract] 
public class StageContract 
{ 
    private int _stageID; 
    private int _projectID; 
    private int _wip; 
    private string _name; 
    private int _position; 

    public StageContract(Stage s) 
    { 
     StageID = s.ID; 
     ProjectID = s.ProjectID; 
     WIP = s.WIP; 
     Name = s.Name; 
     Position = s.Position; 
    } 

    [DataMember] 
    int StageID 
    { 
     get { return _stageID; } 
     set { _stageID = value; } 
    } 

    [DataMember] 
    int ProjectID 
    { 
     get { return _projectID; } 
     set { _projectID = value; } 
    } 

    [DataMember] 
    int WIP 
    { 
     get { return _wip; } 
     set { _wip = value; } 
    } 

    [DataMember] 
    string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    [DataMember] 
    int Position 
    { 
     get { return _position; } 
     set { _position = value; } 
    } 
} 
} 

Die Serviceklasse die Folgendes

using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Controls; 
using KanbanProject.ServiceReference1; 

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 

     InitializeComponent(); 
     this.Loaded += new RoutedEventHandler(MainWindow_Loaded); 

    } 

    void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     var client = new UserServiceClient(); 
     List<StageContract> myList = client.getAllStages(); 
    } 

Bei Ausführung Begegnung, die ich die folgende Fehler:

An unhandled exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' 
occurred in mscorlib.dll 

Additional information: The formatter 
threw an exception while trying to deserialize 
the message: There was an error while trying to 
deserialize parameter http://tempuri.org/:getAllStagesResult. 
The InnerException message was 'Element getAllStagesResult from 
namespace http://tempuri.org/ cannot have child contents to be 
deserialized as an object. Please use XmlNode[] to deserialize 
this pattern of XML.'. Please see InnerException for more details. 

Ich habe versucht, in XmlNode [] Nutzung suchen: http://geekswithblogs.net/TimH/archive/2006/02/09/68857.aspx

Auch dies: WCF: Serializing and Deserializing generic collections

dieses: WCF. IList is deserialized as array. How to make it be any writable list (ArrayList)?

Und: WCF/RESTful DataContract deserialization issue

Vielen Dank im Voraus!

* UPDATE: Nachdem schließlich Deserialisieren auf der Client-Seite traf ich die folgenden:

For List<StageContract> myList = client.getAllStages(); I have Cannot implicitly convert type "object" to "System.Colections.Generic.List<StageContract>" An explicit conversion exists(are you missing a cast?).

* GELÖST: Antwort unten geschrieben.

+0

@jstreet Ich habe es versucht und es funktioniert nicht, der Client weiß nicht über den StageContract-Typ, rathr scheint es ein Objekt des Typs Objekt erhält. Es sagt immer wieder, dass es ein Problem mit dem Deserialisierungsformatierer ist und dass ich XmlNode [] verwende. – Vestilios

+0

@jstreet tat ich, aber es macht es unbrauchbar. Ich habe den Dienstverweis neu konfiguriert, um System.Collections.Generic.List zurückzugeben. Versucht zu spielen, es funktioniert noch nicht. – Vestilios

+0

@jstreet Ich habe den MCVE des Dienstes gepostet. – Vestilios

Antwort

0

Änderung [ServiceKnownType(typeof(List<StageContract>))] zu [ServiceKnownType(typeof(StageContract))]. Sie müssen nie List<T> ... nur T identifizieren. In Ihrem Fall ist T immer noch nicht in KnownTypes.

+0

Vielen Dank für Ihre Hilfe! Ich möchte deine Antwort verbessern, aber die Seite sagt, ich habe noch nicht genug Rep. Ich denke, ich habe es geschafft, das Problem vor Ihrer Antwort zu lösen. Ich habe die Lösung in einer separaten Antwort veröffentlicht. – Vestilios

0

Es wurde gelöst: Das Problem war der Konfigurationsauflistungstyp ServiceReference. Auch wenn ich es vorher auf System.Collections.Generic.List änderte, ließ ich die Always generate message contracts angekreuzt, die wiederum aus irgendeinem Grund den StageContract Typ nicht erkennen ließ.

Danke @jstreet und @Clay!