Динамическая Игнорирование Сериализации XML - PullRequest
6 голосов
/ 19 июня 2011

Я пытаюсь сгенерировать XML-документ в определенном формате. Я хотел бы пропустить сериализацию свойства в зависимости от значения свойства.

public class Parent
{
    public Parent()
    {
        myChild = new Child();
        myChild2 = new Child() { Value = "Value" };
    }
    public Child myChild { get; set; }
    public Child myChild2 { get; set; }
}

public class Child
{
    private bool _set;
    public bool Set { get { return _set; } }

    private string _value = "default";
    [System.Xml.Serialization.XmlText()]
    public string Value
    {
        get { return _value; }
        set { _value = value; _set = true; }
    }
}

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Parent));
x.Serialize(Console.Out, new Parent());

Если Set имеет значение false, я хочу, чтобы все свойство не было сериализовано, мой результирующий xml должен быть

<Parent>
   <myChild2>default</myChild2>
</Parent>

Вместо

<Parent>
   <myChild/>
   <myChild2>default</myChild2>
</Parent>

Есть ли какой-нибудь способ, которым я могу сделать это чисто с IXmlSerializable или чем-то еще?

Спасибо!

Ответы [ 4 ]

6 голосов
/ 19 июня 2011

Существует шаблон ShouldSerialize * (представленный TypeDescriptor, но распознаваемый несколькими другими областями кода, например XmlSerializer):

public bool ShouldSerializemyChild() {
     return myChild != null && myChild.Set;
}

, который должен его отсортировать.

Aболее простой вариант - присвоить ему значение null.

0 голосов
/ 19 июня 2011

Просто написал этот код для развлечения и, возможно, узнаю что-то в процессе. Следует установить для любого свойства значение null, если это свойство содержит метод с именем Set, который возвращает bool, и его текущее значение равно false. Установив значения в false, это должно решить проблему сериализатора. Любые предложения:

public static void RemoveUnsetObjects(object currentObject)
{
    var type = currentObject.GetType();
    if (currentObject is IEnumerable)
    {
        IEnumerable list = (currentObject as IEnumerable);
        foreach (object o in list)
        {
            RemoveUnsetObjects(o);
        }
    }
    else
    {
        foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
        {
            var propertyValue = p.GetValue(currentObject, null);
            if (propertyValue == null)
                continue;
                    var setPropInfo = p.PropertyType.GetProperty("Set", typeof(bool));
            if (setPropInfo != null)
            {
                var isSet = (bool)setPropInfo.GetValue(propertyValue, null);
                if (!isSet)
                {
                    p.SetValue(currentObject, null, null);
                }
            }
            else
            {
                RemoveUnsetObjects(propertyValue);
            }
        }
    }
}
0 голосов
/ 19 июня 2011

Я думаю, что это может сработать, хотя вам, возможно, придется пересмотреть метод Equals

[DefaultValue(new Child())]
public Child myChild{ get; set; }
0 голосов
/ 19 июня 2011

Если массив определяется как mychild, я думаю, что он может преуспеть ...

public class Parent
{
    public Parent()
    {
        myChild = new Child[]{ new Child(){Value = "Value"}};
        //myChild2 = new Child() { Value = "Value" };
    }
    public Child[] myChild { get; set; }
    //public Child myChild2 { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...