2011-12-19 18 views
16

Czy istnieje możliwość wyboru domyślnych wartości atrybutów, których nie ma w pliku xml podczas deserializacji?
Jeśli atrybutu mAge nie ma w pliku xml, chcę użyć wartości domyślnej 18. Czy jest to możliwe?DataContract, domyślna wartość 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; } 
}; 

Edytuj, aby umieścić odpowiedź.

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

Odpowiedz

21

Można użyć [OnDeserialized]

Użyj OnDeserializedAttribute gdy trzeba ustalić wartości na rozszeregować obiektu po jego rozszeregować a przed zwrócony wykres .

[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: Od Twoje komentarze

Dla bool lub int można użyć nullable bool and nullable int więc jeśli te atrybuty wiek i pojedyńcze brakuje w pliku xml wtedy będą null jako dobrze.

tutaj jest szybkie próbki przygotowałem

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

Mogę użyć twojej odpowiedzi, jeśli chcę przesłonić wartość obiektu, ponieważ gdy odwołanie ma wartość null, wiem, że atrybut nie występuje w pliku xml. Ale skąd mogę wiedzieć, czy w pliku xml znajduje się boolean lub int attribut? Jeśli wartość dla bolean jest ustawiona na false lub int jest ustawiona na 0. Nie mogę rozróżnić między nie ustawionymi atrybutami i atrybutami ustawionymi na domyślną wartość C#. – BuzBuza

+0

Jako dezynfekcja spróbuje ustawić domyślne wartości brakujących danych w danej strukturze, więc jedyną opcją jest sprawdzenie poprawnych wartości, np. Gdy zaktualizowałem swoją odpowiedź i sprawdziłem, czy wiek mA == 0, następnie ustaw swoją wartość. –

+0

Możesz używać typów nullable, aby ominąć int i null, sprawdź mój zaktualizowany ans –

2

To powinno zadziałać.

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

Spójrz na stronę this.

+0

Nie, to nie działa (wystarczy przetestować). Deserializator zastępuje domyślną wartość, _even, jeśli ta wartość nie występuje w XML_. –

3

użytkowania [OnDeserializing()]

i ustawić swoje wartości PRZED deserializacji. Tak więc nie ma potrzeby sprawdzania, co może pójść nie tak - co jeśli serial został serializowany na 0?

+0

Po deserializacji typów prostych (na przykład 'double') lub struktur jest to właściwy sposób postępowania. Przed deserializacją ustawiasz pola opcjonalne na pewne domyślne dla aplikacji (lub nieprawidłowe wartości, np. 'Double.NaN'). Deserializacja spowoduje nadpisanie wszystkich wartości podanych w pliku XML i pozostawi nietknięte inne. Po deserializacji nie można odróżnić wartości "set from XML" i wartości zero "not be set". –