2010-02-11 3 views
6

NetworkComponent 클래스의 _updatedComponents라는 객체가있는 배열이 있습니다. 루트 요소 (= 배열)의 이름과 네임 스페이스가 변경되고 개별 NetworkComponent-item의 이름이 구성 요소로 변경되는 방식으로 직렬화해야합니다. 예외가 발생하는 아래 코드가 있습니다.배열을 serialize 할 때 XmlAttributeOverrides를 사용하는 방법은 무엇입니까?

System.InvalidOperationException : 'ComponentSyncService.NetworkComponent []'형식을 반영하는 동안 오류가 발생했습니다. System.InvalidOperationException ---> : XmlRoot 및 XmlType 특성을 ComponentSyncService.NetworkComponent [] 유형에 지정할 수 없습니다.

코드 :

_updatedComponents 무엇
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); 
+0

클래스를 생성 했으므로 System.Xml.Serialization.XmlTypeAttribute 정의를 변경하지 않으려 고하므로 다시 생성 할 때 변경 내용이 손실됩니다. –

답변

8

? 나는 그것이 매우 까다로울 것이라고 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); 
    } 
} 
+0

답장을 보내 주셔서 감사합니다! 내 질문에 상태 : "나는 NetworkComponent 클래스의 개체 _updatedComponents라는 배열이 있습니다." 나는 내일 일하려고 그렇게 일을 떠날 뿐이야. 너무 까다 롭습니다. 나는 왜 완전히 이해하지 못했습니다 ... –

+0

다시 한번 감사드립니다! 나는 아침에 첫 번째로 편집 된 대답을 점검 할 것이다. –

+0

나는 간단한 버전을 시도하고 효과가 있었다. 고마워요! XmlAttributeOverrides 버전을 제공하기 위해 많은 노력을 기울였습니다. 그것이 정말로 필요한 다른 누군가를 도울 수 있기를 바랍니다. –

관련 문제