2011-12-19 22 views
16

¿Hay alguna manera de elegir los valores predeterminados de los atributos que no están en el archivo xml durante la deserialización?
Si el atributo mAge no está presente en el archivo xml, quiero usar un valor predeterminado de 18. ¿Es posible?DataContract, valor predeterminado de 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; } 
}; 

Editar para dar la respuesta.

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

Respuesta

21

Puede utilizar [OnDeserialized]

Utilice la OnDeserializedAttribute cuando es necesario fijar valores en un objeto deserializado después de que haya sido deserializado y antes de que se devuelve el gráfico .

[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: A partir de sus comentarios

Para bool o INT puede utilizar nullable bool and nullable int por lo que si éstos edad y atributos individuales no están presentes en el archivo XML, entonces será nula también.

aquí es muestra rápida preparé

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

Puedo usar su respuesta si deseo anular el valor de un objeto, porque cuando la referencia se establece en nulo, sé que el atributo no está presente en el archivo xml. Pero, ¿cómo puedo saber si hay un atributo booleano o uno int en el archivo xml? Si el valor para un bolean se establece en falso o un int se establece en 0. No puedo distinguir antes de atribuir atributos y atributos asignados al valor predeterminado de C#. – BuzBuza

+0

Como la deserilización intentará establecer valores predeterminados para los datos faltantes en una estructura determinada, su única opción es verificar valores válidos, por ejemplo, cuando actualicé mi respuesta y comprobé si la edad era == 0 y luego establecí su valor. –

+0

Puede usar tipos que aceptan nulos para moverse int y null, por favor mire mi ans actualizado. –

2

Esto debería funcionar.

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

Eche un vistazo a this página.

+0

No, esto no funciona (simplemente lo probé). El deserializador anula tu valor predeterminado, incluso si ese valor no está presente en XML_. –

3

uso [OnDeserializing()]

y debe establecer los valores ANTES de la deserialización. Por lo tanto, no es necesario realizar ningún control, lo que podría ir mal. ¿Qué ocurre si el mAge se serializó para ser 0?

+0

Cuando deserializa tipos simples (por ejemplo, "double") o estructura, este es el camino correcto a seguir. Antes de la deserialización, configura campos opcionales para un valor predeterminado específico de la aplicación (o un valor no válido, por ejemplo, 'double.NaN'). La deserialización sobrescribirá todos los valores dados en el archivo XML y dejará intactos otros. Después de la deserialización, no puede distinguir un valor cero "establecido a partir de XML" y un valor cero "no establecido". –

Cuestiones relacionadas