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