Могу ли я предотвратить десериализацию определенного элемента данных? - PullRequest
5 голосов
/ 29 июля 2010

У меня есть подобный контракт данных

[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    [DataMember]
    public string DM2;

    [DataMember]
    public string DM3;
}

и иногда Я хочу предотвратить десериализацию DM2 при возврате из OperationContract.Примерно так:

[OperationContact]
public MyDC GetMyDC()
{
    MyDC mdc = new MyDC();

    if (condition)
    {
        // Code to prevent DM2 from being deserialized  
    }

    return mdc;
}

Я всегда мог создать новый DataContract, который имеет только DM1 и DM3, и сгенерировать его из экземпляра MyDC, но я хочу посмотреть, возможно ли программно удалить DM2.Является ли это возможным?Как?

Ответы [ 4 ]

6 голосов
/ 10 августа 2010

Один из способов сделать это - установить для свойства EmitDefaultValue объекта DataMemberAttribute значение false:

[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    [DataMember(EmitDefaultValue = false)]
    public string DM2;

    [DataMember]
    public string DM3;
}

Затем установить для этого свойства значение null:

[OperationContact]
public MyDC GetMyDC()
{
    MyDC mdc = new MyDC();

    if (condition)
    {
        // Code to prevent DM2 from being deserialized  
        mdc.DM2 = null;
    }

    return mdc;
}

Таким образом, это свойствоне записывается в выходной поток при сериализации.

http://msdn.microsoft.com/en-us/library/aa347792.aspx

3 голосов
/ 30 июля 2010

Вы имеете в виду сериализацию, а не десериализацию.

Если подготовить класс для сериализации с применением атрибута [DataContract] к классу, сериализуются только члены класса, у которого есть атрибут [DataMember]:

[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    public string DM2;

    [DataMember]
    public string DM3;
}

В некоторых более сложных случаях использование [IgnoreDataMember] может решить вашу проблему. (См. http://msdn.microsoft.com/en-us/library/ms733127.aspx)

Кстати, вы можете сериализовать поля и свойства независимо от их доступности: private, protected, internal, protected internal или public. Вы можете сериализовать любые свойства чтения / записи, а не только поля. О сериализации типов коллекций см. http://msdn.microsoft.com/en-us/library/aa347850.aspx.

2 голосов
/ 06 ноября 2012
[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    public string DM2;

    public bool IsDM2Serializable;

    [DataMember(Name="DM2", EmitDefaultValue = false)]
    public string DM2SerializedConditionally
    {
        get
        {
            if(IsDM2Serializable)
                return null;
            return DM2;
        }
        set { DM2=value; }
    }

    [DataMember]
    public string DM3;
}

Затем установите IsDM2Serializable на false, когда вам нужно его скрыть:

[OperationContact]
public MyDC GetMyDC()
{
    MyDC mdc = new MyDC();

    if (condition)
    {
        // Code to prevent DM2 from being serialized  
        mdc.IsDM2Serializable = false;
    }

    return mdc;
}
0 голосов
/ 30 апреля 2019

Да, мы можем предотвратить сериализацию атрибута. Поместите [DataContract] Annotation на класс и [DataMember] только для сериализованного атрибута. если вы хотите пропустить атрибут, когда значение этого атрибута равно нулю, поместите [DataMember(EmitDefaultValue = false)] в этот атрибут.

Пример:

[DataContract]
public class MyClass 
{
    [DataMember]
    public int Id{ get; set; } 
    [DataMember]
    public string Title { get; set; }
    [DataMember]
    public string MessageBody { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public DateTime SentOn { get; set; } 
}

Примечание. SentOn будет сериализовано, если не равно нулю , а другие будут сериализованы при каждом условии.

...