У меня есть массив, названный _updatedComponents объектов, которые имеют класс NetworkComponent. Я должен сериализировать его в способе, которым изменяются имя и пространство имен корневого элемента (=array), и имя отдельного NetworkComponent-объекта изменилось на компонент. У меня есть код ниже этого, вызывает исключение:
Система. InvalidOperationException: была ошибка при отражении типа 'ComponentSyncService. NetworkComponent []'.---> Система. InvalidOperationException: XmlRoot и атрибуты XmlType не могут быть указаны для типа ComponentSyncService. NetworkComponent [].
Код:
XmlAttributeOverrides xaos = new XmlAttributeOverrides();
// the array itself aka the root. change name and namespace
XmlElementAttribute xea = new XmlElementAttribute(_updatedComponents.GetType());
xea.Namespace = "http://www.example.com/nis/componentsync";
xea.ElementName = "components";
XmlAttributes xas = new XmlAttributes();
xas.XmlElements.Add(xea);
xaos.Add(_updatedComponents.GetType(), xas);
// then the items of the array. just change the name
xea = new XmlElementAttribute(typeof(networkcomponent));
xea.ElementName = "component";
xas = new XmlAttributes();
xas.XmlElements.Add(xea);
xaos.Add(typeof(NetworkComponent), "NetworkComponent", xas);
XmlSerializer serializer = new XmlSerializer(_updatedComponents.GetType(), xaos);
XmlTextWriter writer = new XmlTextWriter(string.Format("{0}\\ComponentSyncWS_{1}.xml",
Preferences.FileSyncDirectory, requestId), Encoding.UTF8);
serializer.Serialize(writer, _updatedComponents);
Что такое _updatedComponents
? Я предполагаю, что это NetworkComponent []
, что очень усложняет задачу. Я бы посоветовал написать тип оболочки:
public class ComponentsMessage {
public NetworkComponent[] Components {get;set;}
}
Тогда вы можете связать правильные атрибуты. Если вам нужно поддерживать специальные атрибуты на NetworkComponent
, вам все равно придется использовать переопределения атрибутов (поэтому я вообще не украшал их), но ComponentsMessage
должен с удовольствием беру атрибуты.
Или просто напишите отдельный DTO и сопоставьте значения.
Если это просто, вы могли бы просто использовать:
[XmlRoot("components", Namespace = XmlNamespace)]
[XmlType("components", Namespace = XmlNamespace)]
public class ComponentsMessage
{
public const string XmlNamespace = "http://www.example.com/nis/componentsync";
[XmlElement("component")]
public NetworkComponent[] Components { get; set; }
}
В качестве альтернативы, если вы должны использовать переопределения атрибутов, я бы все равно использовал объект-оболочку:
public class ComponentsMessage
{
public NetworkComponent[] Components { get; set; }
}
class Program
{
static void Main()
{
NetworkComponent[] _updatedComponents = new NetworkComponent[2] {
new NetworkComponent{},new NetworkComponent{}
};
const string XmlNamespace = "http://www.example.com/nis/componentsync";
XmlAttributeOverrides ao = new XmlAttributeOverrides();
ao.Add(typeof(ComponentsMessage), new XmlAttributes {
XmlRoot = new XmlRootAttribute("components") { Namespace = XmlNamespace },
XmlType = new XmlTypeAttribute("components") { Namespace = XmlNamespace }
});
ao.Add(typeof(ComponentsMessage), "Components", new XmlAttributes {
XmlElements = {
new XmlElementAttribute("component")
}
});
ComponentsMessage msg = new ComponentsMessage { Components = _updatedComponents };
XmlSerializer serializer = new XmlSerializer(msg.GetType(), ao);
serializer.Serialize(Console.Out, msg);
}
}