Win8App 中给定数据的反序列化
Deserialization of given data in Win8App
我有一个 Win8App 和一个 WCF。 Win8App 进行不同的调用,WCF 提供 List
和 ObservableCollections
的自定义 class,如下例中的 Person
。我的问题是每个列表或集合到达我的 Win8App 时都是空的(不是空的)。我发现这是关于反序列化的,但现在该怎么办?
我用 List
、Array
、ObservableCollection
和 IList
或只是一个对象写了一些测试代码,我从来没有得到异常但总是空的(不是空的) ) 集合或一个空的单个对象。是我的WCF/Win8App的反序列化问题还是配置问题?
WCF IService.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();
}
WCF.svc:
public Person GetPerson()
{
return new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) };
}
public List<Person> GetPersons()
{
List<Person> list = new List<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list;
}
public ObservableCollection<Person> GetPersonCollection()
{
ObservableCollection<Person> list = new ObservableCollection<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list;
}
public Person[] GetPersonArray()
{
List<Person> list = new List<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list.ToArray();
}
public IList<Person> GetPersonList()
{
List<Person> list = new List<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list;
}
WCF - Class 人
[DataContract]
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; }
}
}
现在我的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;
}
在我的 Win8App 中,我为 IMyService
和 Person
实现了与 WCF 中相同的代码。
此方法正在调用 WCF:
private void CheckWCFMethods()
{
IMyService client = ServiceBinding.GetClientForService();
var p = client.GetPerson();
IList<Person> iList = client.GetPersonList();
ObservableCollection<Person> collection = client.GetPersonCollection();
Person[] array = client.GetPersonArray();
List<Person> list = client.GetPersons();
#if(DEBUG)
Debug.WriteLine(string.Format("SinglePersonName:{0}\niList.Count:{1}\nCollection.Count:{2}\nArray.Length:{3}\nList.Count:{4}",string.IsNullOrEmpty(p.Name) ? "empty" : p.Name, iList.Count, collection.Count, array.Length, list.Count));
Debug.WriteLine("DONE");
#endif
}
调试结果总是:
**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 中的数据?
如果您需要任何进一步的信息,请告诉我!
** 编辑 **
所以我尝试在客户端为 class 人设置命名空间(class Person
在我的 TestWCF 中名为 "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
** 编辑 **
所以我用我的 windows 8.1 测试应用程序尝试了一些事情,这让我感到困惑,一个正常的 visual studio 服务引用运行良好,而我的 channelfactory "reference" 什么都不做- 无法弄清楚它有什么问题:
我真的很困惑,如果你想自己尝试,你可以在这里下载这个示例 wcf 和 w8.1app(我的 googledrive):
Testfiles
您只需在 win8.1 应用程序中设置端点地址的 uri 并启动 wcf(或在 iis 上发布)。
关于这个主题的任何进一步信息?
如果您按原样复制/粘贴数据/服务合同,那么您可能会遇到 XML 命名空间不匹配的情况。当 XML 通过 WCF 请求/响应中的线路时,其元素位于某些 XML 命名空间内。当您定义 [DataContract]
或 [ServiceContract]
而未明确指定要使用哪个 XML 命名空间时,WCF 将默认使用从 class 本身的命名空间派生的命名空间(即,它的 CLR 命名空间)。
如果您有两个 class,一个在客户端,一个在服务器上用于数据协定,但它们位于不同的 CLR 命名空间中(例如,MyApp.Service.Person
和 MyApp.Client.Person
),那么 WCF 使用的 XML 对应于那些 classes 是不同的。
如果确实如此,请尝试在您的数据协定中明确定义命名空间,这样这种不匹配就不会再发生了:
[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; }
}
}
另一种选择是在您的客户端项目上使用诸如 Visual Studio 上的 "Add Service Reference" 之类的工具,将其指向服务元数据(如果已启用)。该工具将使用适当的命名空间声明创建要在客户端中使用的 classes。
你应该用 [ServiceContract]
属性标记一个界面
[ServiceContract]
public interface IMyService
今天我 运行 遇到了一个问题,即序列化程序在尝试反序列化时间跨度时卡住了。在我的例子中,从要序列化的对象中删除时间跨度解决了这个问题。我能够用整数(秒数)替换时间跨度,不确定这是否适合你,但可能需要检查一下。
我有一个 Win8App 和一个 WCF。 Win8App 进行不同的调用,WCF 提供 List
和 ObservableCollections
的自定义 class,如下例中的 Person
。我的问题是每个列表或集合到达我的 Win8App 时都是空的(不是空的)。我发现这是关于反序列化的,但现在该怎么办?
我用 List
、Array
、ObservableCollection
和 IList
或只是一个对象写了一些测试代码,我从来没有得到异常但总是空的(不是空的) ) 集合或一个空的单个对象。是我的WCF/Win8App的反序列化问题还是配置问题?
WCF IService.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();
}
WCF.svc:
public Person GetPerson()
{
return new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) };
}
public List<Person> GetPersons()
{
List<Person> list = new List<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list;
}
public ObservableCollection<Person> GetPersonCollection()
{
ObservableCollection<Person> list = new ObservableCollection<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list;
}
public Person[] GetPersonArray()
{
List<Person> list = new List<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list.ToArray();
}
public IList<Person> GetPersonList()
{
List<Person> list = new List<Person>();
for (int i = 0; i < 19; i++)
{
list.Add(new Person() { Name = "asdf", IstZeit = new TimeSpan(10000000) });
}
return list;
}
WCF - Class 人
[DataContract]
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; }
}
}
现在我的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;
}
在我的 Win8App 中,我为 IMyService
和 Person
实现了与 WCF 中相同的代码。
此方法正在调用 WCF:
private void CheckWCFMethods()
{
IMyService client = ServiceBinding.GetClientForService();
var p = client.GetPerson();
IList<Person> iList = client.GetPersonList();
ObservableCollection<Person> collection = client.GetPersonCollection();
Person[] array = client.GetPersonArray();
List<Person> list = client.GetPersons();
#if(DEBUG)
Debug.WriteLine(string.Format("SinglePersonName:{0}\niList.Count:{1}\nCollection.Count:{2}\nArray.Length:{3}\nList.Count:{4}",string.IsNullOrEmpty(p.Name) ? "empty" : p.Name, iList.Count, collection.Count, array.Length, list.Count));
Debug.WriteLine("DONE");
#endif
}
调试结果总是:
**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 中的数据?
如果您需要任何进一步的信息,请告诉我!
** 编辑 **
所以我尝试在客户端为 class 人设置命名空间(class Person
在我的 TestWCF 中名为 "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
** 编辑 **
所以我用我的 windows 8.1 测试应用程序尝试了一些事情,这让我感到困惑,一个正常的 visual studio 服务引用运行良好,而我的 channelfactory "reference" 什么都不做- 无法弄清楚它有什么问题:
我真的很困惑,如果你想自己尝试,你可以在这里下载这个示例 wcf 和 w8.1app(我的 googledrive): Testfiles
您只需在 win8.1 应用程序中设置端点地址的 uri 并启动 wcf(或在 iis 上发布)。
关于这个主题的任何进一步信息?
如果您按原样复制/粘贴数据/服务合同,那么您可能会遇到 XML 命名空间不匹配的情况。当 XML 通过 WCF 请求/响应中的线路时,其元素位于某些 XML 命名空间内。当您定义 [DataContract]
或 [ServiceContract]
而未明确指定要使用哪个 XML 命名空间时,WCF 将默认使用从 class 本身的命名空间派生的命名空间(即,它的 CLR 命名空间)。
如果您有两个 class,一个在客户端,一个在服务器上用于数据协定,但它们位于不同的 CLR 命名空间中(例如,MyApp.Service.Person
和 MyApp.Client.Person
),那么 WCF 使用的 XML 对应于那些 classes 是不同的。
如果确实如此,请尝试在您的数据协定中明确定义命名空间,这样这种不匹配就不会再发生了:
[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; }
}
}
另一种选择是在您的客户端项目上使用诸如 Visual Studio 上的 "Add Service Reference" 之类的工具,将其指向服务元数据(如果已启用)。该工具将使用适当的命名空间声明创建要在客户端中使用的 classes。
你应该用 [ServiceContract]
属性标记一个界面
[ServiceContract]
public interface IMyService
今天我 运行 遇到了一个问题,即序列化程序在尝试反序列化时间跨度时卡住了。在我的例子中,从要序列化的对象中删除时间跨度解决了这个问题。我能够用整数(秒数)替换时间跨度,不确定这是否适合你,但可能需要检查一下。