Частичный перехват сериализации XML по умолчанию C#C#

Место общения программистов C#
Ответить
Anonymous
 Частичный перехват сериализации XML по умолчанию C#

Сообщение Anonymous »

Я пытаюсь создать базовый класс сериализации объектов XML, чтобы накопить кучу вещей, которые я узнал за последние несколько лет, чтобы иметь готовый к использованию пример, когда он мне понадобится.
Я хочу добавить функцию комментариев Xml и нашел сообщение о stackoverflow, которое мне в этом помогает. После небольшой очистки мой код выглядит вот так:

Код: Выделить всё

// XmlComment attribute class
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class XmlCommentAttribute(string value) : Attribute
{
public string Value { get; set; } = value;
}

// Usage in code
[XmlComment("This is an example comment that describes the name.")]
[XmlComment("Second comment line")]
public string Name { get; set; }

// Added code to satisfy IXmlSerializable
public void WriteXml(XmlWriter writer)
{
var properties = GetType().GetProperties();

foreach (var propertyInfo in properties)
{
if (HasCommentAttribute(propertyInfo))
HandleCommentAttribute(writer, propertyInfo);

writer.WriteElementString(propertyInfo.Name, propertyInfo.GetValue(this).ToString());
}
}

private static bool HasCommentAttribute(PropertyInfo propertyInfo)
=> propertyInfo.IsDefined(typeof(XmlCommentAttribute), false);

private static void HandleCommentAttribute(XmlWriter writer, PropertyInfo propertyInfo)
{
var comments = propertyInfo.GetCustomAttributes(typeof(XmlCommentAttribute), false);

foreach (var comment in comments)
if (comment is XmlCommentAttribute line)
writer.WriteComment($" {line.Value} ");
}
Результат сериализации: Ура!, хотя и не совсем. Когда я использую данную функцию WriteXml, я сталкиваюсь с проблемами, из-за которых объект не сериализуется должным образом.

Код: Выделить всё

[XmlComment("This is an example comment that describes the name.")]
[XmlComment("Second comment line")]
public string Name { get; set; }

// Added class definition and property below
public class AttributeExample
{
[XmlAttribute]
public int Attrib1 { get; set; } = ushort.MaxValue;

[XmlAttribute]
public int Attrib2 { get; set; } = byte.MaxValue;

[XmlAttribute]
public int Attrib3 { get; set; } = short.MaxValue;
}

public AttributeExample ExampleOfAttributedObject { get; set; }
Это сериализуется в:

Код: Выделить всё


John
ConfigurationPersistence.ExampleConfigObject2+AttributeExample
Что не совсем правильно.
Проблема заключается в том, что функция WriteXml анализирует мой объект в строку с WriteElementString(propertyInfo.Name, propertyInfo.GetValue(this).ToString()) вызов функции.
Как получить этот объект и любой из его дочерних объектов правильно сериализовать, как стандартная реализация WriteXml? Как XmlSerializer это делает? Вам придется перебирать все свойства и свойства этого свойства и сериализовать значение каждого объекта.

ОБНОВЛЕНИЕ
С помощью @dbc мне удалось правильно сериализовать дочерние объекты. Вот моя обновленная функция WriteXml().

Код: Выделить всё

public void WriteXml(XmlWriter writer)
{
var properties = GetType().GetProperties();

foreach (var property in properties)
{
if (HasCommentAttribute(property))
HandleCommentAttribute(writer, property);

var serializer = new XmlSerializer(property.PropertyType);
serializer.Serialize(writer, property.GetValue(this));
}
}
Объект для сериализации:

Код: Выделить всё

[Serializable]
public class ExampleConfigObject
{
[XmlComment("This is an example comment that describes the name.")]
[XmlComment("Second comment line")]
public string Name { get; set; } = "John";

[XmlComment("This is another example comment")]
public string Description { get; set; } = "Doe";

public int Count { get; set; } = int.MaxValue;

public class AttributeExample
{
[XmlAttribute]
public int Attrib1 { get; set; } = ushort.MaxValue;

[XmlAttribute]
public int Attrib2 { get; set; } = byte.MaxValue;

[XmlAttribute]
public int Attrib3 { get; set; } = short.MaxValue;

[XmlElement]
public string Text { get; set; } = "Some text";
}

public AttributeExample ExampleOfAttributedObject { get; set; } = new();

public List ListOfStrings { get; set; } = ["Foo", "Bar"]
}
Выходной XML-документ:

Код: Выделить всё



John

Doe
2147483647

Some text


Foo
Bar


Теперь возникают еще несколько вопросов:
  • Почему в дочерних объектах присутствуют эти атрибуты XMLSchema?
    li>
    Как избежать необходимости реализации ReadXml? Меня не интересует десериализация комментариев, и я хочу просто использовать реализацию XmlReader по умолчанию


Подробнее здесь: https://stackoverflow.com/questions/787 ... on-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»