Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Program Windows Communication Foundation (WCF) może używać dwóch różnych technologii serializacji, aby przekształcić dane w aplikacji w kod XML przesyłany między klientami i usługami: DataContractSerializer
i XmlSerializer
.
Serializator kontraktu danych
Domyślnie program WCF używa DataContractSerializer klasy do serializacji typów danych. Ten serializator obsługuje następujące typy:
Typy pierwotne (na przykład liczby całkowite, ciągi i tablice bajtów), a także niektóre specjalne typy, takie jak XmlElement i DateTime, które są traktowane jako typy pierwotne.
Typy kontraktów danych (typy oznaczone atrybutem DataContractAttribute ).
Typy oznaczone atrybutem SerializableAttribute , które obejmują typy implementujące ISerializable interfejs.
Typy implementujące IXmlSerializable interfejs.
Wiele typowych typów kolekcji, które obejmują wiele typów kolekcji ogólnych.
Wiele typów programu .NET Framework należy do dwóch ostatnich kategorii i dlatego można je serializować. Tablice typów możliwych do serializacji można również serializować. Aby uzyskać pełną listę, zobacz Określanie transferu danych w kontraktach usług.
Parametr DataContractSerializer, używany razem z typami kontraktów danych, jest zalecanym sposobem pisania nowych usług WCF. Aby uzyskać więcej informacji, zobacz Using Data Contracts (Korzystanie z kontraktów danych).
XmlSerializer
Program WCF obsługuje również klasę XmlSerializer . Klasa XmlSerializer nie jest unikatowa dla programu WCF. Jest to ten sam silnik serializacji, który używają usługi sieci Web ASP.NET. Klasa XmlSerializer obsługuje znacznie węższy zestaw typów niż DataContractSerializer klasa, ale umożliwia znacznie większą kontrolę nad wynikowym kodem XML i obsługuje znacznie więcej standardu języka definicji schematu XML (XSD). Nie wymaga również żadnych atrybutów deklaratywnych w typach możliwych do serializacji. Aby uzyskać więcej informacji, zobacz temat Serializacja XML w dokumentacji programu .NET Framework. Klasa XmlSerializer nie obsługuje typów kontraktów danych.
W przypadku używania Svcutil.exe lub funkcji Dodaj odwołanie do usługi w programie Visual Studio w celu wygenerowania kodu klienta dla usługi innej firmy lub uzyskania dostępu do schematu innej firmy odpowiedni serializator jest automatycznie wybierany. Jeśli schemat nie jest zgodny z DataContractSerializer, zostanie wybrany XmlSerializer.
Przełącz się na XmlSerializer
Czasami może być konieczne ręczne przełączenie na XmlSerializer. Dzieje się tak na przykład w następujących przypadkach:
Podczas migrowania aplikacji z usług sieci Web ASP.NET do WCF warto ponownie użyć istniejących typów zgodnych z XmlSerializer, zamiast tworzyć nowe typy umowy danych.
Gdy dokładna kontrola nad plikiem XML wyświetlanym w komunikatach jest ważna, ale dokument WSDL (Web Services Description Language) nie jest dostępny, na przykład podczas tworzenia usługi z typami, które muszą być zgodne z określonym ustandaryzowanym, opublikowanym schematem, który nie jest zgodny z modułem DataContractSerializer.
Podczas tworzenia usług, które są zgodne ze starszym standardem kodowania SOAP.
W tych i innych przypadkach można ręcznie przełączyć się na klasę XmlSerializer, stosując atrybut XmlSerializerFormatAttribute
do swojej usługi, jak pokazano w poniższym kodzie.
[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
[OperationContract]
public void ProcessTransaction(BankingTransaction bt)
{
// Code not shown.
}
}
//BankingTransaction is not a data contract class,
//but is an XmlSerializer-compatible class instead.
public class BankingTransaction
{
[XmlAttribute]
public string Operation;
[XmlElement]
public Account fromAccount;
[XmlElement]
public Account toAccount;
[XmlElement]
public int amount;
}
//Notice that the Account class must also be XmlSerializer-compatible.
<ServiceContract(), XmlSerializerFormat()> _
Public Class BankingService
<OperationContract()> _
Public Sub ProcessTransaction(ByVal bt As BankingTransaction)
' Code not shown.
End Sub
End Class
' BankingTransaction is not a data contract class,
' but is an XmlSerializer-compatible class instead.
Public Class BankingTransaction
<XmlAttribute()> _
Public Operation As String
<XmlElement()> _
Public fromAccount As Account
<XmlElement()> _
Public toAccount As Account
<XmlElement()> _
Public amount As Integer
End Class
'Notice that the Account class must also be XmlSerializer-compatible.
Zagadnienia dotyczące zabezpieczeń
Uwaga / Notatka
Podczas przełączania aparatów serializacji należy zachować ostrożność. W zależności od używanego serializatora ten sam typ może być serializowany do XML na różne sposoby. Jeśli przypadkowo użyjesz nieprawidłowego serializatora, możesz ujawnić informacje z typu, którego nie zamierzasz ujawniać.
Na przykład DataContractSerializer klasa serializuje tylko elementy członkowskie oznaczone atrybutem DataMemberAttribute podczas serializacji typów kontraktów danych. Klasa XmlSerializer serializuje dowolny element członkowski publiczny. Zobacz typ w poniższym kodzie.
[DataContract]
public class Customer
{
[DataMember]
public string firstName;
[DataMember]
public string lastName;
public string creditCardNumber;
}
<DataContract()> _
Public Class Customer
<DataMember()> _
Public firstName As String
<DataMember()> _
Public lastName As String
Public creditCardNumber As String
End Class
Jeśli typ jest nieumyślnie użyty w umowie serwisowej, w której wybrano klasę XmlSerializer, składowa creditCardNumber
jest serializowana, co najprawdopodobniej nie było zamierzone.
Mimo że DataContractSerializer klasa jest domyślna, możesz jawnie wybrać ją dla usługi (chociaż nigdy nie należy tego robić), stosując DataContractFormatAttribute atrybut do typu kontraktu usługi.
Serializator używany dla usługi jest integralną częścią kontraktu i nie można go zmienić, wybierając inne powiązanie lub zmieniając inne ustawienia konfiguracji.
Inne ważne zagadnienia dotyczące zabezpieczeń mają zastosowanie do XmlSerializer klasy. Najpierw zdecydowanie zaleca się, aby każda aplikacja WCF korzystająca z klasy była podpisana przy użyciu XmlSerializer klucza chronionego przed ujawnieniem. To zalecenie ma zastosowanie zarówno w przypadku ręcznego przełączenia na XmlSerializer, jak i automatycznego przełączania (przez Svcutil.exe, Add Service Reference, lub podobne narzędzie). Dzieje się tak, ponieważ XmlSerializer aparat serializacji obsługuje ładowanie wstępnie wygenerowanych zestawów serializacji , o ile są podpisane przy użyciu tego samego klucza co aplikacja. Aplikacja niepodpisana jest całkowicie niechroniona przed możliwością umieszczenia złośliwego modułu, który jest zgodny z oczekiwaną nazwą wstępnie wygenerowanego modułu serializacji, w folderze aplikacji lub globalnej pamięci podręcznej modułów. Oczywiście osoba atakująca musi najpierw uzyskać dostęp do zapisu w jednej z tych dwóch lokalizacji, aby podjąć próbę wykonania tej akcji.
Inne zagrożenie, które istnieje za każdym razem, gdy używasz XmlSerializer, jest związane z dostępem do zapisu w folderze tymczasowym systemu. Silnik XmlSerializer serializacji tworzy i używa tymczasowe zespoły serializacyjne w tym folderze. Należy pamiętać, że każdy proces z dostępem do zapisu do folderu tymczasowego może nadpisać te skompilowane pliki serializacji złośliwym kodem.
Zasady wsparcia dla XmlSerializer
Nie można bezpośrednio stosować XmlSerializeratrybutów zgodnych z parametrami operacji kontraktu ani zwracać wartości. Można je jednak zastosować do komunikatów typowanych (części kontraktu wiadomości), jak pokazano w poniższym kodzie.
[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
[OperationContract]
public void ProcessTransaction(BankingTransaction bt)
{
//Code not shown.
}
}
[MessageContract]
public class BankingTransaction
{
[MessageHeader]
public string Operation;
[XmlElement, MessageBodyMember]
public Account fromAccount;
[XmlElement, MessageBodyMember]
public Account toAccount;
[XmlAttribute, MessageBodyMember]
public int amount;
}
<ServiceContract(), XmlSerializerFormat()> _
Public Class BankingService
<OperationContract()> _
Public Sub ProcessTransaction(ByVal bt As BankingTransaction)
'Code not shown.
End Sub
End Class
<MessageContract()> _
Public Class BankingTransaction
<MessageHeader()> _
Public Operation As String
<XmlElement(), MessageBodyMember()> _
Public fromAccount As Account
<XmlElement(), MessageBodyMember()> _
Public toAccount As Account
<XmlAttribute(), MessageBodyMember()> _
Public amount As Integer
End Class
Po zastosowaniu do elementów członkowskich wiadomości o określonym typie, te atrybuty zastępują właściwości, które są sprzeczne z atrybutami wiadomości o określonym typie. Na przykład w poniższym kodzie ElementName
nadpisuje Name
.
[MessageContract]
public class BankingTransaction
{
[MessageHeader] public string Operation;
//This element will be <fromAcct> and not <from>:
[XmlElement(ElementName="fromAcct"), MessageBodyMember(Name="from")]
public Account fromAccount;
[XmlElement, MessageBodyMember]
public Account toAccount;
[XmlAttribute, MessageBodyMember]
public int amount;
}
<MessageContract()> _
Public Class BankingTransaction
<MessageHeader()> _
Public Operation As String
'This element will be <fromAcct> and not <from>:
<XmlElement(ElementName:="fromAcct"), _
MessageBodyMember(Name:="from")> _
Public fromAccount As Account
<XmlElement(), MessageBodyMember()> _
Public toAccount As Account
<XmlAttribute(), MessageBodyMember()> _
Public amount As Integer
End Class
Atrybut MessageHeaderArrayAttribute nie jest obsługiwany w przypadku używania elementu XmlSerializer.
Uwaga / Notatka
W takim przypadku XmlSerializer zostaje zgłoszony następujący wyjątek, który jest zwalniany przed WCF: "Element zadeklarowany na najwyższym poziomie schematu nie może mieć maxOccurs
> wartość równą 1. Podaj element otoki dla "więcej" używając XmlArray
lub XmlArrayItem
zamiast XmlElementAttribute
, albo stosując styl parametru zatoczonego.
Jeśli otrzymasz taki wyjątek, sprawdź, czy ta sytuacja ma zastosowanie.
WCF nie obsługuje atrybutów SoapIncludeAttribute i XmlIncludeAttribute w kontraktach wiadomości i operacji; zamiast tego użyj atrybutu KnownTypeAttribute.
Typy implementujące interfejs IXmlSerializable
Typy implementujące IXmlSerializable
interfejs są w pełni obsługiwane przez element DataContractSerializer
. Atrybut XmlSchemaProviderAttribute powinien być zawsze stosowany do tych typów w celu kontrolowania ich schematu.
Ostrzeżenie
Jeśli serializujesz typy polimorficzne, musisz zastosować XmlSchemaProviderAttribute do typu, aby upewnić się, że poprawny typ jest serializowany.
Istnieją trzy odmiany typów, które implementują IXmlSerializable
: typy reprezentujące dowolną zawartość, typy reprezentujące pojedynczy element i starsze DataSet typy.
Typy zawartości używają metody dostawcy schematu
XmlSchemaProviderAttribute
określonej przez atrybut . Metoda nie zwracanull
, a IsAny właściwość atrybutu jest pozostawiona na wartości domyślnejfalse
. Jest to najbardziej typowe użycieIXmlSerializable
typów.Typy elementów są używane, gdy typ musi kontrolować własną
IXmlSerializable
nazwę elementu głównego. Aby oznaczyć typ jako typ elementu, ustaw wartość właściwości IsAny na atrybucie XmlSchemaProviderAttribute dotrue
lub zwróćnull
z metody dostawcy schematu. Posiadanie metody dostawcy schematu jest opcjonalne dla typów elementów — można określićnull
zamiast nazwy metody w plikuXmlSchemaProviderAttribute
. Jeśli jednakIsAny
jesttrue
i określono metodę dostawcy schematu, metoda musi zwrócićnull
.Starsze typy DataSet to te typy
IXmlSerializable
, które nie są oznaczone atrybutemXmlSchemaProviderAttribute
. Zamiast tego polegają na metodzie generowania GetSchema schematu. Ten szablon jest używany dlaDataSet
typu, a jego typizowany zestaw danych wywodzi się z klasy we wcześniejszych wersjach platformy .NET Framework, ale jest teraz przestarzały i obsługiwany tylko ze względów zgodności. Nie opieraj się na tym wzorcu i zawsze stosujXmlSchemaProviderAttribute
do swoich typówIXmlSerializable
.
Typy zawartości IXmlSerializable
Podczas serializacji członka danych typu, który implementuje IXmlSerializable
i jest typem zawartości zgodnie z uprzednią definicją, serializator zapisuje element opakowania dla członka danych i przekazuje kontrolę do metody WriteXml. Implementacja WriteXml może generować dowolny XML, w tym dodawać atrybuty do elementu opakowującego. Po zakończeniu WriteXml
serializator zamyka element.
Podczas deserializacji elementu danych typu, który implementuje IXmlSerializable
i jest typem zawartości zgodnie z wcześniejszą definicją, deserializator ustawia czytnik XML na elemencie otoczki dla elementu danych i przekazuje kontrolę do metody ReadXml. Metoda musi odczytać cały element, w tym tagi początkowe i końcowe. Upewnij się, że ReadXml
kod obsługuje przypadek, w którym element jest pusty.
ReadXml
Ponadto implementacja nie powinna polegać na elemencie opakowania, który nosi określoną nazwę. Nazwa jest wybierana przez serializator może się różnić.
Dozwolone jest przypisywanie IXmlSerializable
typów zawartości polimorficznie, na przykład do składowych danych typu Object. Dozwolone jest również, aby wystąpienia typu mogły mieć wartość null. Na koniec można używać IXmlSerializable
typów z włączonym zachowywaniem grafu obiektów i parametrem NetDataContractSerializer. Wszystkie te funkcje wymagają, aby serializator WCF dołączał niektóre atrybuty do elementu opakowującego ("nil" i "type" w przestrzeni nazw wystąpienia schematu XML oraz "Id", "Ref", "Type" i "Assembly" w specyficznej przestrzeni nazw WCF).
Atrybuty do ignorowania podczas implementowania readxml
Przed przekazaniem sterowania do kodu ReadXml
, deserializator bada element XML, wykrywa te specjalne atrybuty XML i odpowiednio je przetwarza. Jeśli na przykład wartość "nil" to true
, wartość null jest deserializowana i ReadXml
nie jest wywoływana. W przypadku wykrycia polimorfizmu zawartość elementu jest deserializowana tak, jakby była innym typem. Wywoływana jest implementacja polimorficznie przypisanego typu ReadXml
. W każdym razie implementacja ReadXml
powinna ignorować te atrybuty specjalne, ponieważ są obsługiwane przez deserializator.
Rozważania związane ze schematem typów zawartości IXmlSerializable
Podczas eksportowania schematu i IXmlSerializable
typu zawartości wywoływana jest metoda dostawcy schematu. Element XmlSchemaSet jest przekazywany do metody dostawcy schematu. Metoda może dodać dowolny prawidłowy schemat do zestawu schematów. Zestaw schematów zawiera schemat, który jest już znany w czasie eksportowania schematu. Gdy metoda dostawcy schematu musi dodać element do zestawu schematów, musi określić, czy element XmlSchema z odpowiednią przestrzenią nazw już istnieje w zestawie. Jeśli tak, metoda dostawcy schematu musi dodać nowy element do istniejącego XmlSchema
. W przeciwnym razie musi utworzyć nową instancję XmlSchema
. Jest ważne, jeśli używane są tablice typów IXmlSerializable
. Na przykład, jeśli masz typ IXmlSerializable
, który zostanie wyeksportowany jako typ "A" w przestrzeni nazw "B", możliwe jest, że w momencie, gdy zostanie wywołana metoda dostawcy schematu, zestaw schematów zawiera już schemat "B" dla typu "ArrayOfA".
Oprócz dodawania typów do klasy XmlSchemaSet, metoda dostawcy schematu dla typów zawartości musi zwracać wartość inną niż null. Może zwrócić element XmlQualifiedName , który określa nazwę typu schematu, który ma być używany dla danego IXmlSerializable
typu. Ta kwalifikowana nazwa służy również jako nazwa kontraktu danych i przestrzeń nazw dla typu danych. Dozwolone jest zwracanie typu, który nie istnieje w zestawie schematów natychmiast po powrocie metody dostawcy schematu. Oczekuje się jednak, że do czasu gdy wszystkie powiązane typy zostaną wyeksportowane (wywołana zostanie metoda Export dla wszystkich odpowiednich typów na XsdDataContractExporter i nastąpi dostęp do właściwości Schemas), typ będzie istniał w zestawie schematów. Uzyskanie dostępu do właściwości Schemas
przed wykonaniem wszystkich odpowiednich wywołań Export
może spowodować powstanie XmlSchemaException. Aby uzyskać więcej informacji na temat procesu eksportowania, zobacz Eksportowanie schematów z klas.
Metoda dostawcy schematu może również zwrócić XmlSchemaType wartość , która ma być używana. Typ może być anonimowy lub nie. Jeśli jest anonimowy, schemat typu IXmlSerializable
jest eksportowany jako typ anonimowy za każdym razem, gdy IXmlSerializable
typ jest używany jako element członkowski danych. Typ IXmlSerializable
wciąż posiada nazwę kontraktu danych oraz przestrzeń nazw. (Jest to określane zgodnie z opisem w Nazwy kontraktów danych, z wyjątkiem tego, że atrybut DataContractAttribute nie może być używany do dostosowywania nazwy). Jeśli nie jest anonimowy, musi być jednym z typów w XmlSchemaSet
. Ten przypadek jest odpowiednikiem zwracania XmlQualifiedName
typu .
Ponadto dla typu jest eksportowana deklaracja elementu globalnego. Jeśli typ nie ma zastosowanego atrybutu XmlRootAttribute , element ma taką samą nazwę i przestrzeń nazw jak kontrakt danych, a jego właściwość "nillable" to true
. Jedynym wyjątkiem jest przestrzeń nazw schematu (http://www.w3.org/2001/XMLSchema
) — jeśli kontrakt danych typu znajduje się w tej przestrzeni nazw, odpowiedni element globalny znajduje się w pustej przestrzeni nazw, ponieważ zabronione jest dodawanie nowych elementów do przestrzeni nazw schematu. Jeśli typ ma zastosowany atrybut XmlRootAttribute
, deklaracja elementu globalnego jest eksportowana przy użyciu następujących właściwości: ElementName, Namespace i IsNullable. Wartości domyślne XmlRootAttribute
zastosowane to nazwa kontraktu danych, pusta przestrzeń nazw i wartość "nillable" to true
.
Te same reguły deklaracji elementów globalnych mają zastosowanie do starszych typów zestawów danych. Należy pamiętać, że XmlRootAttribute
nie może zastąpić deklaracji elementów globalnych dodanych za pomocą kodu niestandardowego, czy to dodanych do XmlSchemaSet
przy użyciu metody dostawcy schematu, czy poprzez GetSchema
dla starszych typów zestawów danych.
Typy elementów IXmlSerializable
IXmlSerializable
typy elementów mają właściwość IsAny
ustawioną na true
lub metoda dostawcy schematu zwraca null
.
Serializacja i deserializacja typu elementu jest bardzo podobna jak serializacja i deserializacja typu zawartości. Istnieją jednak pewne istotne różnice:
Oczekuje się, że implementacja
WriteXml
napisze dokładnie jeden element (który może oczywiście zawierać wiele elementów podrzędnych). Nie należy pisać atrybutów poza tym pojedynczym elementem, wieloma elementami równorzędnymi ani mieszaną zawartością. Element może być pusty.Implementacja
ReadXml
nie powinna odczytywać elementu otoczki. Oczekuje się, że odczytuje jeden element, któryWriteXml
generuje.W przypadku regularnego serializowania typu elementu (na przykład jako element członkowski danych w kontrakcie danych), serializator generuje element opakowania przed wywołaniem elementu
WriteXml
, tak jak w przypadku typów zawartości. Jednak podczas serializacji typu elementu na najwyższym poziomie serializator zwykle nie generuje elementu opakowującego wokół elementu, któryWriteXml
zapisuje, chyba że nazwa główna i przestrzeń nazw są jawnie określone podczas konstruowania serializatora w konstruktorachDataContractSerializer
lubNetDataContractSerializer
. Aby uzyskać więcej informacji, zobacz Serializacja i Deserializacja.Podczas serializacji typu elementu na najwyższym poziomie bez określania nazwy głównej i przestrzeni nazw w czasie konstrukcji, WriteStartObject i WriteEndObject zasadniczo nic nie robią, a WriteObjectContent wywołuje
WriteXml
. W tym trybie obiekt serializowany nie może byćnull
i nie może być przypisywany polimorficznie. Ponadto nie można włączyć zachowywania grafu obiektów ani użyćNetDataContractSerializer
.Podczas deserializacji typu elementu na najwyższym poziomie bez określania nazwy głównej i przestrzeni nazw w czasie konstrukcji IsStartObject zwraca
true
, jeśli może znaleźć początek dowolnego elementu. ReadObject z ustawionym parametremverifyObjectName
natrue
zachowuje się w taki sam sposób jakIsStartObject
przed faktycznym odczytaniem obiektu.ReadObject
następnie przekazuje kontrolę doReadXml
metody.
Schemat wyeksportowany dla typów elementów jest taki sam jak dla XmlElement
typu opisanego we wcześniejszej sekcji, z tą różnicą, że metoda dostawcy schematu może dodać dowolny dodatkowy schemat do XmlSchemaSet typu zawartości. Używanie atrybutu XmlRootAttribute
z typami elementów jest niedozwolone, a deklaracje elementów globalnych nigdy nie są emitowane dla tych typów.
Różnice w porównaniu do XmlSerializer
Interfejs IXmlSerializable
oraz atrybuty XmlSchemaProviderAttribute
i XmlRootAttribute
są również rozumiane przez XmlSerializer. Istnieją jednak pewne różnice w sposobie ich traktowania w modelu kontraktu danych. Ważne różnice zostały podsumowane na poniższej liście:
Metoda dostawcy schematu musi być publiczna, aby była używana w elemecie
XmlSerializer
, ale nie musi być publiczna do użycia w modelu kontraktu danych.Metoda dostawcy schematu jest wywoływana, gdy
IsAny
znajduje siętrue
w modelu kontraktu danych, ale nie w przypadku elementuXmlSerializer
.XmlRootAttribute
Jeśli atrybut nie jest obecny dla zawartości lub starszych typów zestawów danych,XmlSerializer
eksportuje deklarację elementu globalnego w pustej przestrzeni nazw. W modelu kontraktu danych używana przestrzeń nazw jest zwykle przestrzenią nazw kontraktu danych zgodnie z wcześniejszym opisem.
Należy pamiętać o tych różnicach podczas tworzenia typów, które są używane z obu technologii serializacji.
Importowanie schematu IXmlSerializable
Podczas importowania schematu wygenerowanego na podstawie IXmlSerializable
typów istnieje kilka możliwości:
Wygenerowany schemat może być prawidłowym schematem kontraktu danych, zgodnie z opisem w temacie Data Contract Schema Reference (Dokumentacja schematu kontraktu danych). W takim przypadku schemat można zaimportować jak zwykle, a zwykłe typy kontraktów danych są generowane.
Wygenerowany schemat może nie być prawidłowym schematem kontraktu danych. Na przykład metoda dostawcy schematu może wygenerować schemat, który obejmuje atrybuty XML, które nie są obsługiwane w modelu kontraktu danych. W takim przypadku można zaimportować schemat jako typy
IXmlSerializable
. Ten tryb importowania nie jest domyślnie włączony, ale można go łatwo włączyć — na przykład za pomocą/importXmlTypes
przełącznika wiersza polecenia do narzędzia ServiceModel Metadata Tool (Svcutil.exe). Opisano to szczegółowo w temacie Importing Schema to Generate Classes (Importowanie schematu do generowania klas). Należy pamiętać, że musisz pracować bezpośrednio z kodem XML dla wystąpień typu. Możesz również rozważyć użycie innej technologii serializacji, która obsługuje szerszy zakres schematów — zobacz temat dotyczący korzystania z programuXmlSerializer
.Możesz chcieć ponownie użyć istniejących
IXmlSerializable
typów na serwerze proxy zamiast generować nowe. W tym przypadku można użyć funkcji związanej z typami opisanej w temacie Importowanie schematu do generowania typów, aby zidentyfikować typ do ponownego użycia. Odpowiada to użyciu przełącznika/reference
na svcutil.exe, który określa zestaw zawierający typy do ponownego użycia.
Zachowanie starszej wersji elementu XmlSerializer
W programie .NET Framework 4.0 i starszych program XmlSerializer wygenerował tymczasowe zestawy serializacji, pisząc kod języka C# do pliku. Plik został następnie skompilowany w zestawie. To zachowanie miało pewne niepożądane konsekwencje, takie jak spowolnienie czasu uruchamiania serializatora. W programie .NET Framework 4.5 to zachowanie zostało zmienione w celu wygenerowania zestawów bez konieczności używania kompilatora. Niektórzy deweloperzy mogą chcieć zobaczyć wygenerowany kod języka C#. Możesz określić, aby użyć tego starszego zachowania, korzystając z następującej konfiguracji:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.xml.serialization>
<xmlSerializer tempFilesLocation='e:\temp\XmlSerializerBug' useLegacySerializerGeneration="true" />
</system.xml.serialization>
<system.diagnostics>
<switches>
<add name="XmlSerialization.Compilation" value="1" />
</switches>
</system.diagnostics>
</configuration>
Jeśli napotkasz problemy ze zgodnością, takie jak problem z serializacją klasy pochodnej z nowym, niepublicznym przesłonięciem, możesz przywrócić starsze XmlSerializer
zachowanie, używając następującej konfiguracji:
<configuration>
<appSettings>
<add key="System:Xml:Serialization:UseLegacySerializerGeneration" value="true" />
</appSettings>
</configuration>
Alternatywą dla powyższej konfiguracji jest użycie następującej konfiguracji na maszynie z programem .NET Framework 4.5 lub nowszym:
<configuration>
<system.xml.serialization>
<xmlSerializer useLegacySerializerGeneration="true"/>
</system.xml.serialization>
</configuration>
Uwaga / Notatka
Przełącznik <xmlSerializer useLegacySerializerGeneration="true"/>
działa tylko na maszynie z programem .NET Framework 4.5 lub nowszym. Powyższe appSettings
podejście działa we wszystkich wersjach programu .NET Framework.