用DataContractSerializer反序列化对象,能否忽略属性的顺序?

小灰狼 2012-07-02 05:55:04


[DataContract(Name="Person", Namespace="")]
public class Person {

[DataMember(Name="Name", Order=1)]
public String Name { get; set; }
[DataMember(Name="Sex")]
public String Sex { get; set; }
}

class Program
{
static void Main(string[] args) {
Person p = new Person();
p.Name = "Frant";
p.Sex = "Male";

string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\"?><Person xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><Sex>Male</Sex><Name>Smith</Name></Person>";
DataContractSerializer s = new DataContractSerializer(typeof(Person));

using (TextReader reader = new StringReader(xml)) {
using (XmlReader xReader = XmlReader.Create(reader)) {
p = s.ReadObject(xReader) as Person;
Console.WriteLine(p.Name);
Console.WriteLine(p.Sex);
}
}
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
}
}



当被反序列化的字符串 xml 中 Name 和 Sex 节点位置调换之后,反序列化之后的 Person 对象的 Name 属性值就成了空
这就对xml数据节点的顺序有严格的要求

有没有什么办法可以忽略这个顺序要求?
...全文
341 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qldsrx 2012-07-05
  • 打赏
  • 举报
回复
可以自定义的,比如你不喜欢这个默认的DataContractSerializer 而用带强名类型的NetDataContractSerializer,可以这样做:

public class NetDataContractAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
{
ReplaceDataContractSerializerOperationBehavior(description);
}
public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
{
ReplaceDataContractSerializerOperationBehavior(description);
}
public void Validate(OperationDescription description)
{
}

private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
{
DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
description.Behaviors.Remove(dcsOperationBehavior);
description.Behaviors.Add(new NetDataContractSerializerOperationBehavior(description));
}
}
public class NetDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
{
public NetDataContractSerializerOperationBehavior(OperationDescription operationDescription)
: base(operationDescription)
{
}
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
return new NetDataContractSerializer();
}
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
return new NetDataContractSerializer();
}
}
}

使用的时候在方法上添加这样的标记即可用NetDataContract来序列化对象了。

[ServiceContract]
public interface IMgrPerson
{
[OperationContract]
[NetDataContract]
void AddPerson(IPerson Person);

[OperationContract]
[NetDataContract]
IList<IPerson> GetPersons();
}

其实你甚至可以用这个方法自定义一个完全属于自己的序列化类来操作。
小灰狼 2012-07-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

顺序问题还真没留意,也许是为了防止一些不规范的情况出现,再或者是为了提高匹配速度,试试其它的序列化类呢
[/Quote]

用什么序列化办法不是我能决定得了的,这种方式是WCF接口规定使用的,我们只能随它
qldsrx 2012-07-04
  • 打赏
  • 举报
回复
顺序问题还真没留意,也许是为了防止一些不规范的情况出现,再或者是为了提高匹配速度,试试其它的序列化类呢
小灰狼 2012-07-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

去掉 Order=1呢。
[/Quote]
去掉之后还是有要求,顺序不能乱,否则取不到值
宝_爸 2012-07-04
  • 打赏
  • 举报
回复
去掉 Order=1呢。
小灰狼 2012-07-03
  • 打赏
  • 举报
回复
没人了吗?
自己顶一下
小灰狼 2012-07-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

引用 4 楼 的回复:

引用 2 楼 的回复:

没有试验过,从下面的文章看, 如果指定了order[DataMember(Name="Name", Order=1)],就不能忽略它了。


http://stackoverflow.com/questions/1513525/ignore-field-order-in-datacontractserializer


……
[/Quote]

我就是希望它不要去计较顺序
因为从客户端发过来的请求的 xml 是一个移动设备,它是通过组装 xml 文本的方式提交到WCF的,如果对序列化的元素序列有要求,这对客户端来说是件麻烦事
宝_爸 2012-07-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

引用 2 楼 的回复:

没有试验过,从下面的文章看, 如果指定了order[DataMember(Name="Name", Order=1)],就不能忽略它了。


http://stackoverflow.com/questions/1513525/ignore-field-order-in-datacontractserializer


我没有指定 order,但是对顺……
[/Quote]

Order=1 不就是指定顺序吗
小灰狼 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

没有试验过,从下面的文章看, 如果指定了order[DataMember(Name="Name", Order=1)],就不能忽略它了。


http://stackoverflow.com/questions/1513525/ignore-field-order-in-datacontractserializer
[/Quote]

我没有指定 order,但是对顺序也是有要求的
小灰狼 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

确定是xml的话,把
DataContract 换成 Serializable
DataMember 换成 XmlElement
DataContractSerializer 换成 XmlSerializer
ReadObject 换成 Deserialize
[/Quote]

不能换成 Serializable,因为这是用在WCF中的序列化,用什么办法不是我能确定得了的
宝_爸 2012-07-02
  • 打赏
  • 举报
回复
没有试验过,从下面的文章看, 如果指定了order[DataMember(Name="Name", Order=1)],就不能忽略它了。


http://stackoverflow.com/questions/1513525/ignore-field-order-in-datacontractserializer
iyomumx 2012-07-02
  • 打赏
  • 举报
回复
确定是xml的话,把
DataContract 换成 Serializable
DataMember 换成 XmlElement
DataContractSerializer 换成 XmlSerializer
ReadObject 换成 Deserialize

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧