Udostępnij za pośrednictwem


Serializacja XML

Serializacja to proces konwertowania obiektu na formularz, który można łatwo transportować. Na przykład można serializować obiekt i transportować go przez Internet przy użyciu protokołu HTTP między klientem a serwerem. Z drugiej strony, deserializacja rekonstruuje obiekt ze strumienia.

Serializacja XML serializuje tylko pola publiczne i wartości właściwości obiektu w strumieniu XML. Serializacja XML nie zawiera informacji o typie. Jeśli na przykład masz obiekt Book , który istnieje w przestrzeni nazw Biblioteka , nie ma gwarancji, że jest deserializowany do obiektu tego samego typu.

Uwaga / Notatka

Serializacja XML nie konwertuje metod, indeksatorów, pól prywatnych ani właściwości tylko do odczytu (z wyjątkiem kolekcji tylko do odczytu). Aby serializować wszystkie pola i właściwości obiektu, zarówno publiczne, jak i prywatne, użyj DataContractSerializer zamiast serializacji XML.

Centralna klasa w serializacji XML jest klasą XmlSerializer , a najważniejszymi metodami w tej klasie są metody Serialize i Deserialize . Element XmlSerializer tworzy pliki języka C# i kompiluje je w plikach .dll w celu wykonania tej serializacji. Narzędzie generatora serializatora XML (Sgen.exe) zostało zaprojektowane w celu wcześniejszego wygenerowania tych zestawów serializacji w celu wdrożenia za pomocą aplikacji i zwiększenia wydajności uruchamiania. Strumień XML wygenerowany przez moduł XmlSerializer jest zgodny z zaleceniem języka definicji schematu XML (XSD) w wersji 1.0 dla konsorcjum World Wide Web Consortium (W3C). Ponadto wygenerowane typy danych są zgodne z dokumentem zatytułowanym "XML Schema Part 2: Datatypes".

Dane w obiektach są opisywane przy użyciu konstrukcji języka programowania, takich jak klasy, pola, właściwości, typy pierwotne, tablice, a nawet osadzony kod XML w postaci obiektów XmlElement lub XmlAttribute . Istnieje możliwość tworzenia własnych klas, dodawania adnotacji do atrybutów lub używania narzędzia definicji schematu XML do generowania klas na podstawie istniejącego schematu XML.

Jeśli masz schemat XML, możesz uruchomić narzędzie definicji schematu XML, aby utworzyć zestaw klas, które są silnie typizowane do schematu i oznaczone atrybutami. Gdy wystąpienie takiej klasy jest serializowane, wygenerowany kod XML jest zgodny ze schematem XML. Mając do dyspozycji taką klasę, można programować w oparciu o łatwo manipulowalny model obiektowy, mając pewność, że wygenerowany kod XML jest zgodny ze schematem XML. Jest to alternatywa dla używania innych klas na platformie .NET, takich jak klasy XmlReader i XmlWriter , do analizowania i pisania strumienia XML. Aby uzyskać więcej informacji, zobacz Dokumenty XML i dane. Te klasy umożliwiają analizowanie dowolnego strumienia XML. Z kolei użyj klasy XmlSerializer , gdy strumień XML ma być zgodny ze znanym schematem XML.

Atrybuty kontrolują strumień XML wygenerowany przez klasę XmlSerializer , umożliwiając ustawienie przestrzeni nazw XML, nazwy elementu, nazwy atrybutu itd. strumienia XML. Aby uzyskać więcej informacji na temat tych atrybutów i sposobu kontrolowania serializacji XML, zobacz Kontrolowanie serializacji XML przy użyciu atrybutów. Aby zapoznać się z tabelą tych atrybutów, które są używane do kontrolowania wygenerowanego kodu XML, zobacz Atrybuty, które kontrolują serializacji XML.

Klasa XmlSerializer może dodatkowo serializować obiekt i generować zakodowany strumień XML protokołu SOAP. Wygenerowany kod XML jest zgodny z sekcją 5 dokumentu World Wide Web Consortium zatytułowanym "Simple Object Access Protocol (SOAP) 1.1". Aby uzyskać więcej informacji na temat tego procesu, zobacz Jak serializować obiekt jako strumień XML SOAP-Encoded. Aby uzyskać tabelę atrybutów kontrolujących wygenerowany XML, zobacz Atrybuty kontrolujące zakodowaną serializację SOAP.

Klasa XmlSerializer generuje komunikaty PROTOKOŁU SOAP utworzone przez i przekazywane do usług sieci Web XML. Aby kontrolować komunikaty PROTOKOŁU SOAP, można zastosować atrybuty do klas, zwracać wartości, parametry i pola znalezione w pliku usługi sieci Web XML (asmx). Można użyć obu atrybutów wymienionych w sekcji "Atrybuty, które kontrolują serializację XML" i "Atrybuty, które kontrolują zakodowaną serializację SOAP", ponieważ usługa XML Web może korzystać z literału lub zakodowanego stylu SOAP. Aby uzyskać więcej informacji na temat używania atrybutów do kontrolowania kodu XML wygenerowanego przez usługę sieci Web XML, zobacz Serializacja XML z usługami sieci Web XML. Aby uzyskać więcej informacji na temat usług sieci Web SOAP i XML, zobacz Dostosowywanie formatowania komunikatów SOAP.

Zagadnienia dotyczące zabezpieczeń aplikacji XmlSerializer

Podczas tworzenia aplikacji korzystającej z narzędzia XmlSerializer należy pamiętać o następujących elementach i ich implikacjach:

  • Narzędzie XmlSerializer tworzy pliki języka C# (.cs) i kompiluje je do plików .dll w katalogu o nazwie zmiennej środowiskowej TEMP; serializacja występuje w przypadku tych bibliotek DLL.

    Uwaga / Notatka

    Te zestawy serializacji można wygenerować z wyprzedzeniem i podpisać przy użyciu narzędzia SGen.exe. Nie działa to na serwerze usług sieci Web. Innymi słowy, jest przeznaczony tylko do użytku klienta i do serializacji ręcznej.

    Kod i biblioteki DLL są narażone na złośliwy proces podczas tworzenia i kompilacji. Może być możliwe udostępnienie katalogu TEMP przez co najmniej dwóch użytkowników. Udostępnianie katalogu TEMP jest niebezpieczne, jeśli dwa konta mają różne uprawnienia zabezpieczeń, a konto wyższego poziomu uprawnień uruchamia aplikację przy użyciu narzędzia XmlSerializer. W takim przypadku jeden użytkownik może naruszyć zabezpieczenia komputera, zastępując plik .cs lub .dll skompilowany. Aby wyeliminować ten problem, zawsze upewnij się, że każde konto na komputerze ma własny profil. Domyślnie zmienna środowiskowa TEMP wskazuje inny katalog dla każdego konta.

  • Jeśli złośliwy użytkownik wysyła ciągły strumień danych XML do serwera sieci Web (atak typu "odmowa usługi"), narzędzie XmlSerializer będzie nadal przetwarzać dane, dopóki komputer nie będzie działać nisko na zasobach.

    Ten rodzaj ataku jest wyeliminowany, jeśli używasz komputera z uruchomionymi usługami Internet Information Services (IIS), a aplikacja działa w usługach IIS. Usługi IIS posiadają próg, który nie przetwarza strumieni dłuższych niż określona ilość (wartość domyślna to 4 KB). Jeśli tworzysz aplikację, która nie korzysta z IIS i deserializuje za pomocą XmlSerializer, należy zaimplementować podobną bramę, która uniemożliwia atak typu "odmowa usługi".

  • Moduł XmlSerializer serializuje dane i uruchamia dowolny kod przy użyciu dowolnego typu podanego dla niego.

    Istnieją dwa sposoby, w których złośliwy obiekt stanowi zagrożenie. Może on uruchomić złośliwy kod lub wstrzyknąć złośliwy kod do pliku C# utworzonego przez narzędzie XmlSerializer. W drugim przypadku istnieje teoretyczna możliwość, że złośliwy obiekt może w jakiś sposób wstrzyknąć kod do pliku C# utworzonego przez narzędzie XmlSerializer. Mimo że ten problem został dokładnie zbadany i taki atak jest uważany za mało prawdopodobny, należy podjąć środki ostrożności, aby nigdy nie serializować danych z nieznanego i niezaufanego typu danych.

  • Serializowane poufne dane mogą być narażone na zagrożenia.

    Po serializacji danych xmlSerializer można je przechowywać jako plik XML lub inny magazyn danych. Jeśli magazyn danych jest dostępny dla innych procesów lub jest widoczny w intranecie lub Internecie, dane mogą zostać skradzione i wykorzystane złośliwie. Jeśli na przykład utworzysz aplikację, która serializuje zamówienia zawierające numery kart kredytowych, dane są bardzo wrażliwe. Aby temu zapobiec, zawsze chroń magazyn danych i podejmij kroki, aby zachować je prywatne.

Serializacja prostej klasy

Poniższy przykład kodu przedstawia klasę podstawową z polem publicznym.

Public Class OrderForm
    Public OrderDate As DateTime
End Class
public class OrderForm
{
    public DateTime OrderDate;
}

Gdy wystąpienie tej klasy jest serializowane, może wyglądać podobnie do poniższego.

<OrderForm>
    <OrderDate>12/12/01</OrderDate>
</OrderForm>

Aby uzyskać więcej przykładów serializacji, zobacz Przykłady serializacji XML.

Elementy, które można serializować

Następujące elementy można serializować przy użyciu klasy XmlSerializer :

  • Publiczne właściwości odczytu/zapisu i pola klas publicznych.

  • Klasy implementujące ICollection lub IEnumerable.

    Uwaga / Notatka

    Tylko kolekcje są serializowane, a nie właściwości publiczne.

  • Obiekty XmlElement.

  • Obiekty XmlNode.

  • Obiekty Zestawu danych .

Aby uzyskać więcej informacji na temat serializacji lub deserializacji obiektów, zobacz Instrukcje: serializowanie obiektu i Instrukcje: Deserializowanie obiektu.

Zalety używania serializacji XML

Klasa XmlSerializer zapewnia kompletną i elastyczną kontrolę podczas serializacji obiektu jako XML. Jeśli tworzysz usługę sieciową XML, możesz zastosować atrybuty kontrolujące serializację do klas i elementów członkowskich, aby upewnić się, że dane wyjściowe XML są zgodne z określonym schematem.

Na przykład funkcja XmlSerializer umożliwia:

  • Określ, czy pole lub właściwość powinny być zakodowane jako atrybut, czy element.

  • Określ przestrzeń nazw XML do użycia.

  • Określ nazwę elementu lub atrybutu, jeśli nazwa pola lub właściwości jest nieodpowiednia.

Kolejną zaletą serializacji XML jest to, że nie masz ograniczeń dotyczących tworzonych aplikacji, o ile strumień XML, który jest generowany, jest zgodny z danym schematem. Wyobraź sobie schemat używany do opisywania książek. Zawiera on tytuł, autor, wydawcę i element numeru ISBN. Możesz opracować aplikację, która przetwarza dane XML w dowolny sposób, na przykład jako zamówienie książki lub jako spis książek. W obu przypadkach jedynym wymaganiem jest to, że strumień XML jest zgodny ze schematem określonego języka definicji schematu XML (XSD).

Zagadnienia dotyczące serializacji XML

Podczas korzystania z klasy XmlSerializer należy wziąć pod uwagę następujące kwestie:

  • Narzędzie Sgen.exe jest wyraźnie zaprojektowane do generowania zestawów serializacji w celu uzyskania optymalnej wydajności.

  • Serializowane dane zawierają tylko same dane i strukturę klas. Nie uwzględniono tożsamości typu i informacji o zestawie.

  • Można serializować tylko właściwości publiczne i pola. Właściwości muszą mieć publiczne metody dostępu (get i set). Jeśli musisz serializować dane inne niż publiczne, użyj DataContractSerializer klasy, a nie serializacji XML.

  • Klasa musi mieć konstruktor bez parametrów do serializacji przez xmlSerializer.

  • Nie można serializować metod.

  • XmlSerializer może przetwarzać klasy, które implementują funkcję IEnumerable lub ICollection inaczej, jeśli spełniają określone wymagania w następujący sposób.

    Klasa, która implementuje funkcję IEnumerable , musi zaimplementować publiczną metodę Add , która przyjmuje pojedynczy parametr. Parametr metody Add musi być spójny (polimorficzny) z typem zwróconym z właściwości IEnumerator.Current zwróconej z metody GetEnumerator .

    Klasa, która implementuje ICollection oprócz IEnumerable (na przykład CollectionBase), musi mieć publiczną właściwość Item indeksowaną (indeksator w języku C#), która przyjmuje liczbę całkowitą, i musi mieć publiczną właściwość Count typu integer. Parametr przekazany do metody Add musi być tego samego typu co parametr zwrócony z właściwości Item lub jeden z baz tego typu.

    W przypadku klas implementujących ICollection wartości, które mają być serializowane, są pobierane z właściwości indeksowanego elementu , a nie przez wywołanie metody GetEnumerator. Ponadto pola publiczne i właściwości nie są serializowane, z wyjątkiem pól publicznych, które zwracają inną klasę kolekcji (taką, która implementuje ICollection). Aby zapoznać się z przykładem, zobacz Przykłady serializacji XML.

Mapowanie typu danych XSD

Dokument W3C zatytułowany Schemat XML — część 2: Typy danych określa proste typy danych, które są dozwolone w schemacie języka definicji schematu XML (XSD). W przypadku wielu z nich (na przykład int i dziesiętnych) odpowiedni typ danych jest dostępny na platformie .NET. Jednak niektóre typy danych XML nie mają odpowiedniego typu danych platformy .NET, na przykład typu danych NMTOKEN . W takich przypadkach, jeśli używasz narzędzia definicji schematu XML (narzędzie definicji schematu XML (Xsd.exe)) do generowania klas ze schematu, odpowiedni atrybut jest stosowany do elementu członkowskiego ciągu typu, a jego właściwość DataType jest ustawiona na nazwę typu danych XML. Jeśli na przykład schemat zawiera element o nazwie "MyToken" z typem danych XML NMTOKEN, wygenerowana klasa może zawierać składową, jak pokazano w poniższym przykładzie.

<XmlElement(DataType:="NMTOKEN")> _
Public MyToken As String
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;

Podobnie, jeśli tworzysz klasę, która musi być zgodna z określonym schematem XML (XSD), należy zastosować odpowiedni atrybut i ustawić jego właściwość DataType na żądaną nazwę typu danych XML.

Aby uzyskać pełną listę mapowań typów, zobacz właściwość DataType dla dowolnej z następujących klas atrybutów:

Zobacz także