2010-10-08 11 views
9

Mam problemy z serializacją wartości wyliczeniowych.Serializacja XML wyliczeń

Oto kod:

[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 
public class REQUEST 
{ 
    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public string ID; 

    [System.Xml.Serialization.XmlAttributeAttribute()] 
    public REQUESTTypetype Type; 
} 

public enum REQUESTTypetype 
{ 
    One, 
    Two, 
    Three, 
    Four, 
} 

... 

REQUEST request = new REQUEST(); 
request.ID = "1234"; 
request.Type = REQUESTTypetype.One; 

XmlDocument doc = new XmlDocument(); 
MemoryStream ms = new MemoryStream(); 
StreamWriter sw = new StreamWriter(ms); 
XmlSerializer xs = new XmlSerializer(typeof(REQUEST)); 
xs.Serialize(sw, request_group); 
ms.Position = 0; 
doc.Load(ms); 
TestWriteXml(doc, @"C:\xml_test.xml"); 

Wynikiem jest:

<?xml version="1.0" encoding="utf-8" ?> 
<REQUEST ID="1234" /> 

Dlaczego enum nie jest w odcinkach? Korzystam z .NET Framework 2.0.

Dziękuję.

+1

Zgaduję, że czegoś tu brakuje w twoim kodzie, serializujesz "xs.Serialize (sw, request_group)", ale ustawiasz wartość "request". Jaka jest definicja grupy request_group, czy ma ona ustawiony typ? – pstrjds

+0

to powinno być "żądanie", po prostu zmieniam trochę nazwy. – etarvt

+1

Jaki jest kod funkcji TestWriteXml? – pstrjds

Odpowiedz

0

Możesz użyć atrybutu Xml.Serialization.XmlEnum (see here), aby udekorować wartości wyliczenia.

Istnieje też wpis na blogu napisany przez Kurta Claeysa here, który również może pomóc.

+0

Próbowałem, ale to nie zadziałało. – etarvt

-2

Spróbuj umieścić atrybut [Flagi] w wyliczeniu.

+5

To absolutnie nieistotne dla serializacji. – VladV

+0

@vladv - chociaż może nie mieć tutaj zastosowania, zdarzają się sytuacje, gdy [Flags] ma znaczenie dla serializacji. IMO to ważna odpowiedź jako coś do sprawdzenia, szczególnie myślenie o "długim ogonie". –

+0

Zgadzam się z tobą. mój Bad – rauts

2

Czy ten sam problem występuje po ustawieniu typu na "Dwa" lub "Trzy"? Czy to dlatego, że "Jeden" jest wartością domyślną, a więc można założyć? Może to być pewien artefakt ładowania tego do XmlDocument, a następnie zapisywania go za pomocą kodu, który nie został wyświetlony (TestWriteXml).

to nieco zmieniona wersja kodu (Piszę do StringBuilder a następnie ToString'ing go na końcu) ...

REQUEST request = new REQUEST(); 
    request.ID = "1234"; 
    request.Type = REQUESTTypetype.One; 


    StringBuilder sb = new StringBuilder(); 
    StringWriter sw = new StringWriter(sb); 
    XmlSerializer xs = new XmlSerializer(typeof(REQUEST)); 
    xs.Serialize(sw, request); 
    Console.WriteLine(sb.ToString()); 

... stosując dokładnie te same typy jak wspomniałeś powyżej wydaje się działać dobrze. Mam to na konsoli ...

<?xml version="1.0" encoding="utf-16"?> 
<REQUEST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http:/ 
/www.w3.org/2001/XMLSchema" ID="1234" Type="One" /> 

nie zmieniać definicji wniosku lub REQUESTTypetype enum.

+0

Po prostu robiłem to samo i uzyskiwałem te same podstawowe wyniki. Myślę, że problem tkwi w twojej funkcji TestWriteXml. – pstrjds

+0

Po prostu wypróbowałem przykład, który tu podałem i działa dobrze. Jednak mój xml jest znacznie większy niż ten z wieloma wyprowadzonymi elementami itp., A serializacja ignoruje każdy typ wyliczeniowy w wynikowym kodzie XML. Masz pomysł, która część kodu powinienem opublikować, żeby wszystko było bardziej zrozumiałe? – etarvt

+0

Proponuję zacząć od twojego przykładu i dodawać rzeczy z powrotem, aż przestaną działać. Zgaduję, że gdzieś w dół linii (klasa dzieci lub wnuków) brakuje jakiegoś atrybutu lub coś oczyszcza. – pstrjds

0

W rzeczywistym kodzie, jest członkiem:

  • publicznego
  • odczyt + zapis (dla pól: nie tylko do odczytu, na właściwości: Get publicznego + zestaw)
  • typu publicznym

?

Wszystkie 3 muszą być prawdziwe. W przypadku typów zagnieżdżonych każdy typ macierzysty w zagnieżdżeniu musi być publiczny.

Dodatkowe rzeczy, które wykluczają go:

  • pustych i zerowy
  • jest jeśli DefaultValue
  • ShouldSerialize lub Określony zwrócone false
  • Jest IXmlSerializable
+0

Również w przypadku klas (nie wyliczeniowych) musi istnieć publiczny konstruktor bez parametrów. –

17

znalazłem co było źle.Dla każdego typu enum

[System.Xml.Serialization.XmlAttributeAttribute()] 
public REQUESTTypetype Type; 

mam to:

[System.Xml.Serialization.XmlIgnoreAttribute()] 
public bool TypeSpecified; 

I w kodzie mam to zrobić:

request.Type = REQUESTTypetype.One; 
request.TypeSpecified = true; 

To działa dobrze teraz. Powinienem opublikować je w moim pytaniu, ale w ogóle nie zwracałem uwagi na tych "określonych" członków. Dzięki za twoje odpowiedzi.