2011-12-19 39 views
16

有没有一种方法可以选择在反序列化过程中不在xml文件中的属性的默认值?
如果mAge属性不存在于xml文件中,我想使用默认值18.是否有可能?DataContract,默认DataMember值

[DataContract] 
public class Person 
{ 
    public Person() 
    { 
    } 
    [DataMember(Name = "Name")] 
    public string mName { get; set; } 
    [DataMember(Name = "Age")] 
    public int mAge { get; set; } 
    [DataMember(Name = "Single")] 
    public bool mIsSingle { get; set; } 
}; 

编辑要放的答案。

[DataContract] 
public class Person 
{ 
    public Person() 
    { 
    } 
    [DataMember(Name = "Name")] 
    public string mName { get; set; } 
    [DataMember(Name = "Age")] 
    public int? mAge { get; set; } 
    [DataMember(Name = "Single")] 
    public bool? mIsSingle { get; set; } 

    [System.Runtime.Serialization.OnDeserialized] 
    void OnDeserialized(System.Runtime.Serialization.StreamingContext c) 
    { 
     mAge = (mAge == null ? 18 : mAge); // 18 is the default value 
    } 
} 

回答

21

您可以使用[OnDeserialized]

使用OnDeserializedAttribute 当你需要它已被反序列化并返回 图形之前之后 反序列化对象来修复价值。

[DataContract] 
public class Person 
    { 
    public Person() 
    { 
    } 
    [DataMember(Name = "Name")] 
    public string mName { get; set; } 
    [DataMember(Name = "Age")] 
    public int mAge { get; set; } 
    [DataMember(Name = "Single")] 
    public bool mIsSingle { get; set; } 



    [System.Runtime.Serialization.OnDeserialized] 
    void OnDeserialized(System.Runtime.Serialization.StreamingContext c) 
    { 
     mAge = (mAge == 0) ?18:mAge; 
    } 
    } 
} 

编辑:从您的评论

对于bool或INT可以使用nullable bool and nullable int 因此,如果这些年龄和单属性的XML文件中缺少那么他们将是空的为好。

这里是我准备

using System.Runtime.Serialization; 
using System.ServiceModel; 
using MySpace; 
using System.ServiceModel.Channels; 
using System; 
namespace MySpace 
{ 

[DataContract] 
public class Person 
    { 
    public Person() 
    { 
    } 
    [DataMember(Name = "Name")] 
    public string mName { get; set; } 
    [DataMember(Name = "Age")] 
    public int? mAge { get; set; } 
    [DataMember(Name = "Single")] 
    public bool? mIsSingle { get; set; } 



    [System.Runtime.Serialization.OnDeserialized] 
    void OnDeserialized(System.Runtime.Serialization.StreamingContext c) 
    { 
     mAge = (mAge == null ? 18 : mAge); 
    } 
    } 
} 
[ServiceContract] 
public interface IService 
{ 
    [OperationContract] 
    Person Method(Person dd); 
} 

public class Service : IService 
{ 
    public Person Method(Person dd) 
    { 
    return dd; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    string Url = "http://localhost:8000/"; 
    Binding binding = new BasicHttpBinding(); 
    ServiceHost host = new ServiceHost(typeof(Service)); 
    host.AddServiceEndpoint(typeof(IService), binding, Url); 
    host.Open(); 
    ChannelFactory<IService> fac = new ChannelFactory<IService>(binding); 
    fac.Open(); 
    IService proxy = fac.CreateChannel(new EndpointAddress(Url)); 
    Person d = new Person(); 
    d.mName = "BuzBuza"; 

    Console.WriteLine("Data before calling service " + (d.mAge == null ? " null " : d.mAge.Value.ToString())); 
    Console.WriteLine("Data before calling service " + (d.mIsSingle == null ? "null" : d.mIsSingle.Value.ToString())); 
    d = proxy.Method(d); 
    fac.Close(); 
    host.Close(); 
    Console.WriteLine("Data after calling service " + (d.mAge == null ? " null " : d.mAge.Value.ToString())); 
    Console.WriteLine("Data after calling service " + (d.mIsSingle == null ? "null" : d.mIsSingle.Value.ToString())); 

    Console.ReadLine(); 
    } 
} 
+0

如果我想覆盖一个对象的值,我可以使用你的答案,因为当引用设置为null时,我知道attribut不存在于xml文件中。但是我怎么能知道XML文件中是否存在布尔型或int型属性?如果一个布尔值的值被设置为false或者一个int值被设置为0,那么我就不能将无用的attribut和attribut分配给默认的c#值。 – BuzBuza 2011-12-19 20:48:39

+0

由于deserilization会尝试为给定结构中的缺失数据设置默认值,所以您唯一的选择是检查有效值,例如我更新了我的答案并检查年龄是否为0,然后设置您的值。 – 2011-12-19 20:58:14

+0

你可以使用可为空的类型来解决int和null,plz检查我更新的ans – 2011-12-19 21:21:32

2

这应该有效。

[DataContract] 
public class Person 
    { 
    public Person() 
    { 
    } 
    [DataMember(Name = "Name")] 
    public string mName { get; set; } 
    [DataMember(Name = "Age")] 
    public int mAge = 18; 
    [DataMember(Name = "Single")] 
    public bool mIsSingle { get; set; } 
    }; 

看看this页面。

+0

不,这不起作用(只是测试它)。反序列化器会覆盖您的默认值,即使该值不在XML_中,也是如此。 – 2016-12-13 13:39:20

3

使用[OnDeserializing()]

快速出样和你设定值的反序列化了。所以没有必要的检查,可能会出错 - 如果mAge被序列化为0会怎么样?

+0

当您反序列化简单类型(例如'double')或结构体时,这是正确的方法。在反序列化之前,您可以将可选字段设置为一些特定于应用程序的默认值(或无效值,例如'double.NaN')。反序列化将覆盖XML文件中给出的所有值,并保持其他值不变。反序列化后,您无法区分“从XML设置”的零值和“未设置”的零值。 – 2017-07-10 12:52:42

相关问题