Подтвердить что ты не робот

Игнорировать свойство во время сериализации XML, но не во время десериализации

В С#, как я могу заставить XmlSerializer игнорировать свойство во время сериализации, но не во время десериализации? (Или как мне сделать то же самое с Json.net?)

Чтобы предотвратить сериализацию свойства, вы можете добавить атрибут XmlIgnore:

[XmlIgnore]
public int FooBar {get;set;}

Это приведет к тому, что тег <FooBar> будет опущен во время сериализации.

Однако это также означает, что тег <FooBar> будет игнорироваться во время десериализации.

В моем случае я принимаю массив элементов от пользователя в запросе, и для каждого элемента пользователь может указать свойство действия, если он хочет добавить, изменить или удалить элемент. Я хочу использовать один и тот же объект модели для вызовов списка GET и не хочу возвращать это свойство действия. Я ожидаю, что это будет довольно распространенный случай.

Другой вариант использования: скажем, у вас есть объект окружности

public class Circle
{
    public double Radius { get; set; }
}

и вы измените его, чтобы добавить свойство диаметра

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }
}

Вы можете сериализовать только диаметр, но все же сможете десериализовать xml файлы в старом формате, который содержит только радиус.

Я сделал свое исследование и ничего не нашел, поэтому этот вопрос

Решение. Я понял решение. Я могу добавить свойство ShouldSerialize, которое всегда возвращает false, подробности в этой документации MSDN

(это решение можно было бы добавить в качестве фактического ответа, если этот вопрос будет вновь открыт)

4b9b3361

Ответ 1

Если вы хотите игнорировать элемент при сериализации с помощью XmlSerializer, вы можете использовать XmlAttributeOverrides:

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("YourElementName"));
overrides.Add(typeof(YourClass), "YourElementName", attribs);

XmlSerializer ser = new XmlSerializer(typeof(YourClass), overrides);
ser.Serialize(...

Ответ 2

Это решение, описанное Manoj:

Если вы хотите пресечь сериализацию определенного свойства Foo, но все же сможете десериализовать его, вы можете добавить метод public bool ShouldSerializeFoo(), который всегда возвращает false.

Пример:

public class Circle2
{
    public double Diameter { get; set; }
    public double Radius { get { return Diameter / 2; } set { Diameter = value*2; } }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public bool ShouldSerializeRadius() {return false;}
}

Это приведет к тому, что радиус не будет сериализован, но все же разрешит его десериализацию.

Этот метод должен быть общедоступным для XMLSerializer, чтобы его найти, поэтому, чтобы избежать загрязнения пространства имен, вы можете добавить атрибут EditorBrowsable, чтобы скрыть его от IDE. К сожалению, это скрытие работает только в том случае, если сборка упоминается как DLL в вашем текущем проекте, но нет, если вы редактируете фактический проект с помощью этого кода.