Варианты сериализации XML в .NET - PullRequest
2 голосов
/ 11 мая 2010

Я создаю сервис, который возвращает XML (без SOAP, без ATOM, просто старый XML). Скажем, у меня уже есть доменные объекты с данными, и мне просто нужно преобразовать их в формат XML. Какие варианты у меня есть на .NET?

Требования:

  • Преобразование не 1: 1. Скажем, у меня есть свойство Address типа Address с вложенными свойствами, такими как Line1, City, Postcode и т. Д. Это может привести к XML, например <xaddr city="...">Line1, Postcode</xaddr>, то есть совсем другому.
  • Некоторые элементы / атрибуты XML являются условными, например, если Клиент младше 18 лет, XML должен содержать некоторую дополнительную информацию.
  • Мне нужно только сериализовать объекты в XML, другое направление (XML в объекты) не важно
  • Некоторые технологии, то есть контракты данных, используют атрибуты .NET. Другие средства настройки (внешняя конфигурация XML, классы собеседников и т. Д.) Были бы плюсом.

Вот варианты, которые я вижу как момент. Исправления / дополнения будут приветствоваться.

  • Конкатенация строк - забудь, это была шутка:)
  • Linq 2 XML - полный контроль, но довольно много рукописного кода, потребуется хороший набор модульных тестов
  • Просмотр движков в ASP.NET MVC (или даже теоретически веб-формах), логика в контроллерах. Вопрос в том, как его структурировать, у меня может быть простой движок правил в контроллере и один шаблон представления для каждого возможного вывода или логика принятия решения непосредственно в шаблоне. У обоих есть свои плюсы и минусы.
  • Сериализация XML - я не уверен насчет гибкости здесь
  • Контракты на данные от WCF - также не уверены в гибкости, плюс они будут работать в простом приложении ASP.NET MVC (не-WCF-сервис)? Являются ли они супер-набором стандартной сериализации XML сейчас?
  • Если он существует, некоторые сопоставитель XML-объект . Чем больше я думаю об этом, тем больше думаю, что я ищу что-то подобное, но не могу найти ничего подходящего.

Есть комментарии / другие варианты?

1 Ответ

8 голосов
/ 11 мая 2010

Сериализация Xml работает хорошо. Вы используете атрибуты для его настройки.

Вы можете условно включать элементы.

РЕДАКТИРОВАТЬ: Я обновил код, чтобы отразить ваш обновленный вопрос.

[XmlRoot("pdata")]  // this element name used if serialized to doc root
public class PersonalData
{
     [XmlElement]  // with no name here, elt name = prop name
     public string Name;

     [XmlElement]  // with no name here, elt name = prop name
     public int Age;

     [XmlElement("xaddr")]  // override xml element name 
     public AddressData Address;

     [XmlElement] 
     public Under18Info Other {get; set;}

     // serialize the above element, only if Age < 18
     [XmlIgnore] // do not serialize the *Specified" property in any case
     private bool OtherSpecified {
        get { return Age < 18; }
     }
}

public class AddressData
{
     [XmlIgnore]   // do not serialize (see Composite prop)
     public string Line1 { get; set;}

     [XmlAttribute("city")] // serialize as an attribute on the parent 
     public string City {get; set;}

     [XmlIgnore]   // do not serialize 
     public string Postcode {get; set;}

     [XmlText]   // serialize as the Text node
     public string Composite 
     {
        get { return Line1 + ", " + Postcode; }
        set {
          var split = value.Split(',');
          Line1 = split[0];
          Postcode= split[1];
        }
     }
}

Затем, чтобы сериализовать экземпляр этого в строку, например:

var pdata = new PersonalData
    {
        Name = "Gordon Brown",
        Age = 57,
        Address = new AddressData
        {
            Line1 = "10 Downing St.",
            Postcode = "1QR 3E4",
            City = "London"
        }
    };

var ns= new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add( "", "");
var s1 = new XmlSerializer(typeof(PersonalData));
var builder = new System.Text.StringBuilder();
var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
using ( var writer = System.Xml.XmlWriter.Create(builder, xmlws))
{
    s1.Serialize(writer, pdata, ns);
}
string xml = builder.ToString();

Результаты:

<pdata>
  <Name>Gordon Brown</Name>
  <Age>57</Age>
  <xaddr city="London">10 Downing St., 1QR 3E4</xaddr>
</pdata>
...