Сериализация свойства как атрибута XML в элементе

У меня есть следующий класс:

[Serializable]
public class SomeModel
{
    [XmlElement("SomeStringElementName")]
    public string SomeString { get; set; }

    [XmlElement("SomeInfoElementName")]
    public int SomeInfo { get; set; }
}

Который (при заполнении некоторыми тестовыми данными) и сериализованный с помощью XmlSerializer.Serialize () приводит к следующему XML:

<SomeModel>
  <SomeStringElementName>testData</SomeStringElementName>
  <SomeInfoElementName>5</SomeInfoElementName>
</SomeModel>

Что мне нужно иметь это:

<SomeModel>
  <SomeStringElementName Value="testData" />
  <SomeInfoElementName Value="5" />
</SomeModel>

Есть ли способ указать это как атрибуты без написания моего собственного кода сериализации?

Ответы на вопрос(2)

Решение Вопроса

Вам понадобятся классы-обёртки:

public class SomeIntInfo
{
    [XmlAttribute]
    public int Value { get; set; }
}

public class SomeStringInfo
{
    [XmlAttribute]
    public string Value { get; set; }
}

public class SomeModel
{
    [XmlElement("SomeStringElementName")]
    public SomeStringInfo SomeString { get; set; }

    [XmlElement("SomeInfoElementName")]
    public SomeIntInfo SomeInfo { get; set; }
}

или более общий подход, если вы предпочитаете:

public class SomeInfo<T>
{
    [XmlAttribute]
    public T Value { get; set; }
}

public class SomeModel
{
    [XmlElement("SomeStringElementName")]
    public SomeInfo<string> SomeString { get; set; }

    [XmlElement("SomeInfoElementName")]
    public SomeInfo<int> SomeInfo { get; set; }
}

А потом:

class Program
{
    static void Main()
    {
        var model = new SomeModel
        {
            SomeString = new SomeInfo<string> { Value = "testData" },
            SomeInfo = new SomeInfo<int> { Value = 5 }
        };
        var serializer = new XmlSerializer(model.GetType());
        serializer.Serialize(Console.Out, model);
    }
}

будет производить:

<?xml version="1.0" encoding="ibm850"?>
<SomeModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SomeStringElementName Value="testData" />
  <SomeInfoElementName Value="5" />
</SomeModel>
 25 апр. 2017 г., 15:35
Я знаю, что это несколько устарело, но я бы добавил неявные операции приведенияT вSomeInfo<T> и наоборот.
 IUnknown04 июл. 2012 г., 16:21
Да, это дает мне схему XML, которая мне нужна, но добавляет ненужный уровень косвенности и сложности модели. Теперь вместо Object.SomeProperty у меня есть Object.SomeProperty.Value. Я понимаю, что, возможно, не смогу использовать его в обоих случаях, используя встроенную сериализацию, но в этом суть вопроса.
 04 июл. 2012 г., 16:23
Вот как работает встроенный сериализатор.

Вид, использоватьXmlAttribute вместоXmlElement, но это не будет похоже на то, что вы хотите. Это будет выглядеть следующим образом:

<SomeModel SomeStringElementName="testData"> 
</SomeModel> 

Единственный способ достичь того, чего вы хотите (изначально), - это иметь свойства, указывающие на объекты с именами SomeStringElementName и SomeInfoElementName, где класс содержит один метод получения с именем & quot; value & quot ;. Вы можете сделать еще один шаг и использовать DataContractSerializer, чтобы классы-обертки могли быть закрытыми. XmlSerializer не будет читать частные свойства.

// TODO: make the class generic so that an int or string can be used.
[Serializable]  
public class SerializationClass
{
    public SerializationClass(string value)
    {
        this.Value = value;
    }

    [XmlAttribute("value")]
    public string Value { get; }
}


[Serializable]                     
public class SomeModel                     
{                     
    [XmlIgnore]                     
    public string SomeString { get; set; }                     

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

    [XmlElement]
    public SerializationClass SomeStringElementName
    {
        get { return new SerializationClass(this.SomeString); }
    }               
}
 IUnknown04 июл. 2012 г., 16:16
Привет, Крис, да, я мог бы использовать XmlAttribute, но, как ты сказал, он не дает нужного мне результата. Я надеялся получить то, что мне нужно, без написания собственного кода сериализации.
 04 июл. 2012 г., 16:36
@ Неизвестно - я собрал один из возможных способов достижения того, чего ты хочешь. Создание классов для получения узла не очень красиво, поэтому, если кто-то знает о лучшем способе, мне также будет интересно.

Ваш ответ на вопрос