C# WCF未反序列化值类型。神秘行为
服务代码:C# WCF未反序列化值类型。神秘行为,c#,.net,wcf,c#-4.0,C#,.net,Wcf,C# 4.0,服务代码: [ServiceContract] public interface IServices { [OperationContract] [XmlSerializerFormat] GetProductsResponse Getproducts(GetProductsRequest productsrequest); [OperationContract] SaveProductsResponse Save
[ServiceContract]
public interface IServices
{
[OperationContract]
[XmlSerializerFormat]
GetProductsResponse Getproducts(GetProductsRequest productsrequest);
[OperationContract]
SaveProductsResponse SaveProducts1(SaveProductsRequest1 productsrequest);
}
public class GetProductsRequest
{
[XMLElement]
public string id;
[XMLElement,typeof(Person)]
public Person[] Persons;
}
[DataContract]
public class SaveProductsRequest1
{
[DataMember]
public List<Person> Persons;
}
[DataContract]
public class Person
{
[DataMember]
public int Id;
[DataMember]
public string Name;
[DataMember]
public Sex Sex;
}
[DataContract]
public enum Sex
{
[EnumMember]
Male,
[EnumMember]
Female
}
[服务合同]
公共接口设备
{
[经营合同]
[XmlSerializerFormat]
GetProductsResponse Getproducts(GetProductsRequest productsrequest);
[经营合同]
SaveProducts响应SaveProducts1(SaveProductsRequest1 productsrequest);
}
公共类GetProductsRequest
{
[XMLElement]
公共字符串id;
[XMLElement,类型(人)]
公众人士[]人;
}
[数据合同]
公共类存储产品请求1
{
[数据成员]
公众人士名单;
}
[数据合同]
公共阶层人士
{
[数据成员]
公共int Id;
[数据成员]
公共字符串名称;
[数据成员]
公共性;
}
[数据合同]
公众人口性别
{
[委员]
男,,
[委员]
女性
}
客户:
ServicesClient client = new ServicesClient();
SaveProductsRequest1 req = new SaveProductsRequest1();
req.Persons = new List<Person> { new Person { Id = 10, Name = "Al", Sex = Sex.Female} }.ToArray();
client.SaveProducts1(req);
ServicesClient客户端=新ServicesClient();
SaveProductsRequest1 req=新的SaveProductsRequest1();
req.Persons=new List{new Persons{Id=10,Name=“Al”,Sex=Sex.Female}}.ToArray();
client.SaveProducts1(请求);
我能够在服务端获取值'Al'(字符串)。但值10和阳(值类型)在服务端重置为默认值(0和阳)
只有当我在服务契约(本例中为GetProducts)中的任何一个方法使用XmlSerializerFormat时,以及当我在GetProducts类中为任何数组属性和一个附加字符串属性放置XMLElement时,才会发生这种情况
WCF运行时有问题吗
只有在服务契约(本例中为GetProducts)中的任何一个方法具有XmlSerializerFormat时,才会发生这种情况
在这种情况下,WCF使用XmlSerializer
序列化数据。因此,无论是[DataContract]
还是[DataMember]
都不适用。如果确实必须使用XmlSerializer
,并且需要进一步控制XML序列化,则需要使用其特定属性,例如[xmlement]
,[xmlAttribute]
,[XmlIgnore]
。很好的做法是明确,以避免由于无意中重命名字段或属性而导致难以发现的问题:
public class Person
{
[XmlElement("Id")]
public int Id { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlIgnore] // don't tell the stranger
public Sex Sex { get; set; }
}
还要注意,
[Serializable]
属性与XML序列化和数据协定序列化无关。它仅与二进制序列化相关。您的服务合同是否用ServiceContract
属性修饰:
[ServiceContract]
public interface IServices
{
// ...
}
我只是希望您没有在这里向我们展示一些不同的东西。我已经使用您的服务器端代码设置了一个测试WCF服务,并且再次使用您的示例客户端代码设置了一个测试客户端,它工作得很好:
如您所见,传输了1
Person
,所有3个值都完好无损。如果在您的终端发生了一些不同的事情,可能与配置文件中的配置选项有关,但从根本上说:代码是有效的。我正在使用.NET 4.5进行测试,请包括Person类。我们可以看看Person
是如何声明的吗?datacontract看起来如何?嗯。。。您的个人
课程无法完成。它必须缺少Sex
数据member@Al.Net性在哪里?我担心的是,我们会关注一个问题,而这个问题并不存在于我们正在展示的课程的明显不同版本中。我有两个问题。我希望在getproducts中使用xmlserialization(这很好),但在saveproducts中使用datacontractserialization。我怎样才能做到这一点呢?那么,我不应该在同一个服务契约中使用操作契约级别中的两个SerializationOn类型吗?不必用属性标记它们,也不必使用属性。假定为“元素”,字段工作正常-这是完全受支持的。使用XML序列化程序和数据协定序列化程序的两个属性装饰您的成员。我同时使用[Serializable]和[DataContract]装饰了您的成员。但仍然没有对值类型进行反序列化。我之所以要使用两种序列化类型,是因为GetProducts是旧代码,并且使用xmlattribute。但saveproduct是一个新的需求,应该使用它datacontractserialization@MarcGravell嗯,需要再来一杯咖啡……现在回答还为时过早,所以:-)是的,你说得对。是的,我有服务合同。现在编辑它。Thanks@Al.Net不过,你可以看到——如果忽略这些细节,我们很难找到正确的答案;)我可以看看你的服务合同吗?因为我的代码也运行良好。只有当我的一个方法具有[XMLSerialzeFormat]属性(在我的例子中,它是Getproducts)时,问题才会出现。请张贴您的服务合同、运营合同及其类别members@Al.Net我完全掌握了你问题中的代码;我对这个问题所做的更改是为其他3种类型添加虚拟存根:[DataContract]公共类SaveProductsResponse{}
,[DataContract]公共类getproductsresquest{}
和[DataContract]公共类GetProductsResponse{}
。关于信息,我也在没有使用[DataContract]
的情况下对2个“产品”相关类型进行了测试-它仍然可以正常工作。让我也试试新的示例MarcLet我发布了我的GetProductsRequest。您可以尝试在您的示例中使用我的GetProductsRequest吗。因为我在使用该classIf时遇到了问题,我从属性Persons的GetProductRequest中删除了XMLElement属性,并将其作为XMLArrayItem属性,一切都很好。我可以知道为什么这个XMLElement属性会导致值类型反序列化问题吗?