2011-12-19 64 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