2011-12-19 41 views
16

Có cách nào để chọn giá trị mặc định của thuộc tính không có trong tệp xml trong quá trình deserialization không?
Nếu thuộc tính mAge không có trong tệp xml, tôi muốn sử dụng giá trị mặc định là 18. Có thể không?DataContract, mặc định DataMember giá trị

[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; } 
}; 

Chỉnh sửa để đặt câu trả lời.

[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 
    } 
} 

Trả lời

21

Bạn có thể sử dụng [OnDeserialized]

Sử dụng OnDeserializedAttribute khi bạn cần phải sửa chữa giá trị trên một đối tượng deserialized sau khi nó đã được deserialized và trước khi graph được trả về.

[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; 
    } 
    } 
} 

EDIT: Từ nhận xét của bạn

Đối bool hoặc int bạn có thể sử dụng nullable bool and nullable int vì vậy nếu các lứa tuổi và thuộc tính Độc thân đang thiếu trong file xml sau đó họ sẽ được null là tốt.

đây là mẫu nhanh chóng tôi đã chuẩn bị

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

Tôi có thể sử dụng câu trả lời của bạn nếu tôi muốn ghi đè giá trị của một đối tượng, bởi vì khi tham chiếu được đặt thành null, tôi biết rằng thuộc tính không có trong tệp xml. Nhưng làm thế nào tôi có thể biết nếu một boolean hoặc một attribut là hiện diện trong tập tin xml? Nếu giá trị cho bolean được đặt thành false hoặc int được đặt thành 0. Tôi không thể phân phối được thừa kế không được gán và attribut được đặt thành giá trị mặc định C#. – BuzBuza

+0

Khi deserilization sẽ cố gắng thiết lập giá trị mặc định cho dữ liệu bị mất trong một cấu trúc nhất định, vì vậy lựa chọn duy nhất của bạn là kiểm tra các giá trị hợp lệ, ví dụ như tôi đã cập nhật câu trả lời và kiểm tra xem age mAge == 0 có đặt giá trị của bạn không. –

+0

Bạn có thể sử dụng các loại nullable để nhận được xung quanh int và null, plz kiểm tra ans cập nhật của tôi –

2

Điều này sẽ hiệu quả.

[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; } 
    }; 

Hãy xem trang this.

+0

Không, tính năng này không hoạt động (chỉ cần kiểm tra). Trình Deserializer ghi đè giá trị mặc định của bạn, _even nếu giá trị đó không có trong XML_. –

3

sử dụng [OnDeserializing()]

và bạn thiết lập giá trị của bạn TRƯỚC deserialization. Vì vậy, không có kiểm tra cần thiết, mà có thể đi sai - nếu mAge được tuần tự là 0?

+0

Khi bạn deserialize các loại đơn giản (ví dụ: 'double') hoặc structs đây là cách chính xác để đi. Trước khi deserialization bạn đặt trường tùy chọn cho một số mặc định ứng dụng cụ thể (hoặc giá trị không hợp lệ, ví dụ: 'double.NaN'). Deserialization sẽ ghi đè tất cả các giá trị được đưa ra trong tệp XML và để người khác bị ảnh hưởng. Sau khi deserialization bạn không thể phân biệt một giá trị bằng không "thiết lập từ XML" và một giá trị bằng không "không được thiết lập". –