WCF测试客户端如何反序列化数据合同?如何反序列化DataContract对象的List

时间:2016-05-02 22:46:46

标签: c# wpf wcf deserialization datacontract

我已经实现了一个由WCF测试客户端成功反序列化的数据协定。现在,我如何在我制作的自定义客户端中执行此操作?

我的合同是:

[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; }
    }
}
}

服务类具有以下内容:

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

在客户端:

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();
    }

执行时遇到以下错误:

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.

我尝试查看XmlNode []用法:http://geekswithblogs.net/TimH/archive/2006/02/09/68857.aspx

此外:WCF: Serializing and Deserializing generic collections

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

而且:WCF/RESTful DataContract deserialization issue

提前谢谢!

*更新: 在客户端最终反序列化之后,我遇到了以下内容:

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?).

*已解决:答案发布在下面。

2 个答案:

答案 0 :(得分:1)

[ServiceKnownType(typeof(List<StageContract>))]更改为[ServiceKnownType(typeof(StageContract))]。您永远不必识别List<T> ...仅T。在您的情况下,T仍然不在KnownTypes中。

答案 1 :(得分:0)

解决了它:问题是ServiceReference配置集合类型。即使我之前将其更改为System.Collections.Generic.List,我仍然会勾选Always generate message contracts,而这又因为某些原因而无法识别StageContract类型。

谢谢@jstreet和@Clay!