C# Win8App中给定数据的反序列化

C# Win8App中给定数据的反序列化,c#,.net,wcf,serialization,deserialization,C#,.net,Wcf,Serialization,Deserialization,我有一个Win8App和一个WCF。Win8App进行不同的调用,WCF提供自定义类的列表和可观察集合,如以下示例中的Person。我的问题是,当每个列表或集合到达我的Win8App时,它们都是空的(不是空的)。我发现这是关于反序列化的,但现在该怎么办 我用列表、数组、可观察的集合和IList编写了一些测试代码,或者只编写了一个对象,但我从未得到异常,而是总是空(非空)集合或空的单个对象。这是我的WCF/Win8App的反序列化问题还是配置问题 WCF.cs: [ServiceContract]

我有一个Win8App和一个WCF。Win8App进行不同的调用,WCF提供自定义类的
列表
可观察集合
,如以下示例中的
Person
。我的问题是,当每个列表或集合到达我的Win8App时,它们都是空的(不是空的)。我发现这是关于反序列化的,但现在该怎么办

我用
列表
数组
可观察的集合
IList
编写了一些测试代码,或者只编写了一个对象,但我从未得到异常,而是总是空(非空)集合或空的单个对象。这是我的WCF/Win8App的反序列化问题还是配置问题

WCF.cs:

[ServiceContract]
public interface IMyService
{       
    [OperationContract(Name = "GetPerson")]
    Person GetPerson();

    [OperationContract(Name = "GetPersons")]
    List<Person> GetPersons();

    [OperationContract(Name = "GetPersonArray")]
    Person[] GetPersonArray();

    [OperationContract(Name = "GetPersonList")]
    IList<Person> GetPersonList();

    [OperationContract(Name = "GetPersonCollection")]
    ObservableCollection<Person> GetPersonCollection();        
}

现在我的Win8App

通过ChannelFactory设置ServiceReference:

public static IMyService GetClientForService()
{
    EndpointAddress endpointAddress = new EndpointAddress("http://localhost:12345/Service1.svc");

    BasicHttpBinding basicHttpBinding = new BasicHttpBinding();     

    ChannelFactory<IMyService> channelFactory = channelFactory = new ChannelFactory<IMyService>(basicHttpBinding, endpointAddress);
    IMyService client = channelFactory.CreateChannel();            

    return client;
}
调试结果始终为:

**DEBUGRESULT**
SinglePersonName:empty
IList.Count:0
Collection.Count:0
Array.Length:0
List.Count:0
DONE
但当我通过WCF Testclient直接执行WCF时,我得到:

SinglePersonName: asdf
IList.Count:19
Collection.Count:19
Array.Length:19
List.Count:19


我尝试设置
[KnownType]
[ServiceKnownType]
(服务器和客户端),但它没有改变任何东西。我以前只写过2或3个WCF,但从未处理过反序列化问题,因为当我通过Visual Studio设置ServiceReference时,集合类型和字典集合类型是自动设置的(或通过简单的单击)。所以我是ChannelFactory的新手,也不熟悉服务器端和客户端的序列化编码

在Win8App中反序列化数据可以做什么,应该做什么


如果您需要任何进一步的信息,请让我知道


**编辑**

因此,我尝试在客户端为person类设置一个名称空间(
classperson
位于TestWCF中名为“DataContracts”的文件夹中):

但结果仍然是这样的:

**DEBUGRESULT**
SinglePersonName:empty
IList.Count:0
Collection.Count:0
Array.Length:0
List.Count:0
DONE

**编辑**

因此,我在我的windows 8.1测试应用程序中尝试了一些方法,但它让我感到困惑的是,普通的visual studio服务引用做得很好,而我的channelfactory“引用”什么也没做——我无法找出它到底出了什么问题:

我真的很困惑,如果你想自己尝试一下,你可以在这里下载这个wcf和w8.1app示例(我的googledrive):

您只需在win8.1应用程序中设置EndpointAddress的uri并启动wcf(或在iis上发布)


有关此主题的任何进一步信息?

如果按原样复制/粘贴数据/服务契约,则可能会得到XML命名空间不匹配。当在WCF请求/响应中通过连接的XML时,其元素位于某些XML名称空间中。当定义
[DataContract]
[ServiceContract]
而未明确指定要使用的XML命名空间时,WCF将默认为从类本身的命名空间派生的命名空间(即其CLR命名空间)

如果您有两个类,一个在客户机上,一个在服务器上,用于数据协定,但它们位于不同的CLR命名空间中(例如,
MyApp.Service.Person
MyApp.client.Person
),则WCF使用的与这些类对应的XML是不同的

如果确实如此,请尝试在数据协定上显式定义名称空间,以便不再发生这种不匹配:

[DataContract(Namespace = "http://my.company.com/contracts")]
public class Person
{
    private string name;
    private string email;
    private TimeSpan istZeit;

    public Person()
    {

    }

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

    [DataMember]
    public TimeSpan IstZeit
    {
        get { return istZeit; }
        set { istZeit = value; }
    }

    [DataMember]
    public string Email
    {
        get { return email; }
        set { email = value; }
    }
}

另一种选择是在客户端项目上使用VisualStudio上的“添加服务引用”之类的工具,将其指向服务元数据(如果已启用)。该工具将使用适当的命名空间声明创建要在客户端中使用的类。

您应该使用
[ServiceContract]
属性标记intarface

[ServiceContract]
public interface IMyService

今天我遇到了一个问题,序列化程序在尝试反序列化时间跨度时遇到了阻塞。在我的例子中,从要序列化的对象中删除timespan修复了这个问题。我可以用整数(秒数)替换timespan,不确定这是否适用于您,但可能需要检查一下。

当您说“在我的Win8App中,我为IMyService和WCF中的Person-like实现了相同的代码”时,您是否将数据协定和服务协定定义从服务复制/粘贴到您的客户端应用程序?@carlosfigueira-是的,我创建了一个类,其中实现了接口和所有需要的类?不对?就像谷歌告诉我的那样-我应该如何实现服务接口?对不起,我的错-我已经设置了这个属性。忘记在这里的示例代码中编写它了!因为“添加服务引用”-这是我的问题。我已使用
basichttauthentication
修改了WCF,但无法添加引用,因为在它抛出错误之前,我必须进行大约100次身份验证。这就是为什么我想通过ChannelFactory添加“参考”。身份验证工作正常,但现在我遇到了自定义类、泛型列表和集合的(反)序列化问题。我将尝试使用namespace属性,但是这个属性对列表和集合有帮助吗?我的名称空间看起来像URL吗?将
[DataContract(命名空间=”http://localhost:port/Service1.svc“”]
足够了,还是我必须指定类在wcf中的哪个文件夹中?将我的问题-在客户端添加的名称空间更新为
classperson
,但它没有改变任何事情。我必须将
[KnownType]
[ServiceKnownType]
设置在任何地方吗?我查看了您根据更新的问题链接的.zip文件;服务器端的类
Person
中的
[DataContract]
属性没有定义任何
命名空间(因此它将采用默认值,类似于
”http://schemas.datacontract.org/2004/07/WcfService1.DataContracts“
),而在客户端,您拥有它。尝试在类的客户端和服务器版本上定义相同的名称空间,这样应该可以开始工作了。谢谢!在两者上设置名称空间
[DataContract(Namespace = "http://localhost:12345/DataContracts")]
public class Person{}
**DEBUGRESULT**
SinglePersonName:empty
IList.Count:0
Collection.Count:0
Array.Length:0
List.Count:0
DONE
[DataContract(Namespace = "http://my.company.com/contracts")]
public class Person
{
    private string name;
    private string email;
    private TimeSpan istZeit;

    public Person()
    {

    }

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

    [DataMember]
    public TimeSpan IstZeit
    {
        get { return istZeit; }
        set { istZeit = value; }
    }

    [DataMember]
    public string Email
    {
        get { return email; }
        set { email = value; }
    }
}
[ServiceContract]
public interface IMyService