2013-02-21 17 views
5

Próbuję napisać narzędzie ONIX do importowania książek w języku C#. Zacząłem od utworzenia klas za pomocą Xsd2Code i otrzymałem ogromny plik zawierający wszystkie właściwości, które po kilku poprawkach nie powodują żadnego błędu podczas deserializacji.Deserialize Enum z Xml za pomocą właściwości Value w C#

Próbuję deserializować cały element za jednym razem, w duży obiekt w pamięci, a następnie zrobić z nim (na przykład zapisać do bazy danych).

Sposób, w jaki Xsd2Code generował klasy, poza tym, że istnieje wiele właściwości, jest trochę dziwny, przynajmniej dla mnie.

Oto jedna z klas, które powinny być właściwością obiektu Produktu:

public partial class NotificationType 
{ 
    public NotificationTypeRefname refname { get; set; } 
    public NotificationTypeShortname shortname { get; set; } 

    public SourceTypeCode sourcetype { get; set; } 

    public List1 Value { get; set; } 
} 

chciałbym skierować swoją uwagę na tej linii:

public List1 Value { get; set; } 

„List1” jest enum , zdefiniowane w ten sposób:

public enum List1 
{ 
    [System.Xml.Serialization.XmlEnum("01")] 
    Item01, 

    [System.Xml.Serialization.XmlEnum("02")] 
    Item02, etc... 

Mój problem polega na tym, że podczas deserializacji wszystkie pola przekształcają deserializację poprawną y Z WYJĄTKÓW.

Próbowałem dekorowania właściwości z XmlEnum ("NotificationType") etc ... nic!

To jest mój kod deserializacji:

var p = new Product(); 
XmlSerializer pserializer = new XmlSerializer(p.GetType()); 
object pDeserialized = pserializer.Deserialize(reader); 
p = (Product) pDeserialized; 

ten sposób ten element wygląda w XML:

<NotificationType>03</NotificationType> 

Obiekt, który jest w C# dla obiektu Produkt jest:

public NotificationType NotificationType { get; set; } 

Jeśli zmienię to na:

public List1 NotificationType { get; set; } 

deserializacji poprawnie pokazuje „Item03”, co oznacza, że ​​nie czyta co jest w formacie XML. JEŻELI zostawiam to tak jak powyżej, właściwość "Value" klasy NotificationType nigdy nie jest wypełniona i zawsze pokazuje Item01 (domyślną wartość Enum).

Mam wyczerpane wszystkie możliwe pytania na temat SO i wyszukiwań internetowych, dlaczego DLACZEGO wartość ta działa z niektórymi typami (ciągi znaków), ale nie wylicza. Czy czegoś brakuje?

Przepraszamy za długi pytanie i kodu. Doceń wszelkie światło, które każdy może rzucić na ten temat. Utknąłem z tym przez cały dzień.

Odpowiedz

1

spróbuj dodać [System.Xml.Serialization.XmlTextAttribute()] do nieruchomości public List1 Value { get; set; }.

+0

To działa! Mógłbym przysiąc, że próbowałem tego wcześniej. Myślę, że jest to atrybut, który pozwala bibliotece deserialization wiedzieć, co właściwość do wypełnienia jako wartość elementu XML. –

+0

Nie działa dla mnie. –

+0

Crazy, pracuję także nad ONIX! To samo działa również dla mnie, dla pojedynczej wartości z Enum. Czy masz szczęście z opróżnianiem szeregu Enums? Takich jak List91 []? –

2

Spróbuj tego:

public partial class NotificationType 
{ 
    public NotificationTypeRefname refname { get; set; } 
    public NotificationTypeShortname shortname { get; set; } 
    public SourceTypeCode sourcetype { get; set; } 

    public List1 Value { get { 
     return (List1)Enum.Parse(typeof(List1), 
      Enum.GetName(typeof(List1), int.Parse(List1Value) - 1)); 
    }} 

    [XmlText] 
    public string List1Value { get; set; } 
} 

[UPDATE]

od:

  1. Próbowałem też najpierw dekoracji element z atrybutem XmlText, ale następujący wyjątek był występujące:

    Nie można przekształcić do postaci szeregowej obiektu typu "ConsoleApplication1.NotificationType". Rozważ zmianę typu elementu XmlText "ConsoleApplication1.NotificationType.Value" z ConsoleApplication1.List1 na ciąg znaków lub ciąg znaków.

  2. i chcesz uniknąć moje pierwsze podejście w odpowiedzi

prawdziwym rozwiązaniem jest to, że oprócz stosowania atrybutu ValueXmlText, wszyscy pozostali członkowie powinni być ozdobione XmlIgnoreAttribute. Uważam, że samo korzystanie z XmlText nie jest rozwiązaniem gwarantowanym, ponieważ wyniki zależą od istnienia innych członków.

public class NotificationType 
{ 
    [XmlIgnore] // required 
    public NotificationTypeRefname refname { get; set; } 
    [XmlIgnore] // required 
    public NotificationTypeShortname shortname { get; set; } 
    [XmlIgnore] // required 
    public SourceTypeCode sourcetype { get; set; } 

    [XmlText] // required 
    public List1 Value { get; set; } 
} 
+0

Podsumowując, działa to również w mniej bezpośredni sposób. Naprawdę nie lubię wprowadzać dodatkowej właściwości dla każdego przypadku, ponieważ w specyfikacji ONIX jest ich około 200. –

+0

@CristiCotovan, Mam również "InvalidOperationException", gdy próbuję odpowiedzi pbz. Jego odpowiedź była moją pierwszą próbą, ale zawiodła (i nadal się nie udaje), więc szukałem obejścia. –

+0

Działa tutaj, nie wiem, dlaczego ci się nie udało. Wolę to w ten sposób, ponieważ jest czystszy i dodaję inne rzeczy na wierzchu (takie jak opisywanie każdego wariantu Enum i wyodrębnianie go za pomocą Reflection, aby wyświetlać przyjazne dla użytkownika znaczenie dla każdej wartości wyliczenia). –

Powiązane problemy