Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Windows Communication Foundation (WCF) incluye un nuevo motor de serialización, el DataContractSerializer. DataContractSerializer se traduce entre objetos de .NET Framework y XML, en ambas direcciones. En este tema se explica cómo funciona el serializador.
Al serializar objetos de .NET Framework, el serializador entiende una variedad de modelos de programación de serialización, incluido el nuevo modelo de contrato de datos . Para obtener una lista completa de los tipos admitidos, consulte Tipos admitidos por el serializador de contrato de datos. Para obtener una introducción a los contratos de datos, consulte Uso de contratos de datos.
Al deserializar XML, el serializador usa las XmlReader clases y XmlWriter . También admite las XmlDictionaryReader clases y XmlDictionaryWriter para permitir que genere XML optimizado en algunos casos, como cuando se usa el formato XML binario WCF.
WCF también incluye un serializador complementario, NetDataContractSerializer. El NetDataContractSerializer:
- No es seguro. Para obtener más información, vea Guía de seguridad de BinaryFormatter.
- Es similar a los serializadores BinaryFormatter y SoapFormatter porque también emite nombres de tipo de .NET Framework como parte de los datos serializados.
- Se utiliza cuando se comparten los mismos tipos en los extremos de serialización y deserialización.
Tanto DataContractSerializer como NetDataContractSerializer derivan de una clase base común, XmlObjectSerializer.
Advertencia
DataContractSerializer serializa cadenas que contienen caracteres de control con un valor hexadecimal inferior a 20 como entidades XML. Esto puede provocar un problema con un cliente que no es WCF al enviar estos datos a un servicio WCF.
Creación de una instancia de DataContractSerializer
La construcción de una instancia de DataContractSerializer es un paso importante. Después de la construcción, no se puede cambiar ninguna de las configuraciones.
Especificación del tipo raíz
El tipo raíz es el tipo de las instancias que se serializan o deserializan.
DataContractSerializer tiene muchas sobrecargas de constructor, pero, como mínimo, se debe proporcionar un tipo raíz mediante el type
parámetro .
No se puede usar un serializador creado para un tipo raíz determinado para serializar (o deserializar) otro tipo, a menos que el tipo se derive del tipo raíz. En el ejemplo siguiente se muestran dos clases.
[DataContract]
public class Person
{
// Code not shown.
}
[DataContract]
public class PurchaseOrder
{
// Code not shown.
}
<DataContract()> _
Public Class Person
' Code not shown.
End Class
<DataContract()> _
Public Class PurchaseOrder
' Code not shown.
End Class
Este código construye una instancia de DataContractSerializer
que solo se puede usar para serializar o deserializar instancias de la clase Person
.
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
// This can now be used to serialize/deserialize Person but not PurchaseOrder.
Dim dcs As New DataContractSerializer(GetType(Person))
' This can now be used to serialize/deserialize Person but not PurchaseOrder.
Especificación de tipos conocidos
Si el polimorfismo está implicado en los tipos que se serializan que aún no se controlan mediante el KnownTypeAttribute atributo o algún otro mecanismo, se debe pasar una lista de posibles tipos conocidos al constructor del serializador mediante el knownTypes
parámetro . Para obtener más información sobre los tipos conocidos, vea Tipos conocidos del contrato de datos.
En el ejemplo siguiente se muestra una clase , LibraryPatron
que incluye una colección de un tipo específico, .LibraryItem
La segunda clase define el LibraryItem
tipo. La tercera y cuatro clases (Book
y Newspaper
) heredan de la LibraryItem
clase .
[DataContract]
public class LibraryPatron
{
[DataMember]
public LibraryItem[] borrowedItems;
}
[DataContract]
public class LibraryItem
{
// Code not shown.
}
[DataContract]
public class Book : LibraryItem
{
// Code not shown.
}
[DataContract]
public class Newspaper : LibraryItem
{
// Code not shown.
}
<DataContract()> _
Public Class LibraryPatron
<DataMember()> _
Public borrowedItems() As LibraryItem
End Class
<DataContract()> _
Public Class LibraryItem
' Code not shown.
End Class
<DataContract()> _
Public Class Book
Inherits LibraryItem
' Code not shown.
End Class
<DataContract()> _
Public Class Newspaper
Inherits LibraryItem
' Code not shown.
End Class
El código siguiente construye una instancia del serializador mediante el knownTypes
parámetro .
// Create a serializer for the inherited types using the knownType parameter.
Type[] knownTypes = new Type[] { typeof(Book), typeof(Newspaper) };
DataContractSerializer dcs =
new DataContractSerializer(typeof(LibraryPatron), knownTypes);
// All types are known after construction.
' Create a serializer for the inherited types using the knownType parameter.
Dim knownTypes() As Type = {GetType(Book), GetType(Newspaper)}
Dim dcs As New DataContractSerializer(GetType(LibraryPatron), knownTypes)
' All types are known after construction.
Especificar el nombre raíz predeterminado y el espacio de nombres
Normalmente, cuando se serializa un objeto, el nombre predeterminado y el espacio de nombres del elemento XML más externo se determinan según el nombre y el espacio de nombres del contrato de datos. Los nombres de todos los elementos internos se determinan a partir de los nombres de los miembros de datos y están en el mismo espacio de nombres que el contrato de datos. En el siguiente ejemplo, se establecen los valores de Name
y Namespace
en los constructores de las clases DataContractAttribute y DataMemberAttribute.
[DataContract(Name = "PersonContract", Namespace = "http://schemas.contoso.com")]
public class Person2
{
[DataMember(Name = "AddressMember")]
public Address theAddress;
}
[DataContract(Name = "AddressContract", Namespace = "http://schemas.contoso.com")]
public class Address
{
[DataMember(Name = "StreetMember")]
public string street;
}
<DataContract(Name:="PersonContract", [Namespace]:="http://schemas.contoso.com")> _
Public Class Person2
<DataMember(Name:="AddressMember")> _
Public theAddress As Address
End Class
<DataContract(Name:="AddressContract", [Namespace]:="http://schemas.contoso.com")> _
Public Class Address
<DataMember(Name:="StreetMember")> _
Public street As String
End Class
La serialización de una instancia de la Person
clase produce XML similar al siguiente.
<PersonContract xmlns="http://schemas.contoso.com">
<AddressMember>
<StreetMember>123 Main Street</StreetMember>
</AddressMember>
</PersonContract>
Sin embargo, puede personalizar el nombre predeterminado y el espacio de nombres del elemento raíz pasando los valores de los parámetros rootName
y rootNamespace
al constructor DataContractSerializer. Observe que el rootNamespace
no afecta al espacio de nombres de los elementos contenidos que corresponden a miembros de datos. Solo afecta al espacio de nombres del elemento extremo.
Estos valores se pueden pasar como cadenas o instancias de la XmlDictionaryString clase para permitir su optimización mediante el formato XML binario.
Establecer la cuota máxima de objetos
Algunas sobrecargas del constructor de DataContractSerializer
tienen un parámetro maxItemsInObjectGraph
. Este parámetro determina el número máximo de objetos que el serializador serializa o deserializa en una sola ReadObject llamada de método. (El método siempre lee un objeto raíz, pero este objeto puede tener otros objetos en sus miembros de datos. Esos objetos pueden tener otros objetos, etc.) El valor predeterminado es 65536. Tenga en cuenta que al serializar o deserializar matrices, cada entrada de matriz cuenta como un objeto independiente. Además, tenga en cuenta que algunos objetos pueden tener una representación de memoria grande, por lo que es posible que esta cuota por sí sola no sea suficiente para evitar un ataque por denegación de servicio. Para obtener más información, consulte Consideraciones de seguridad para datos. Si necesita aumentar esta cuota más allá del valor predeterminado, es importante hacerlo tanto en los lados de envío (serialización) como de recepción (deserialización), ya que se aplica a ambos al leer y escribir datos.
Recorridos de ida y vuelta
Un recorrido de ida y vuelta se produce cuando un objeto se deserializa y se vuelve a serializar en una operación. Por lo tanto, pasa de XML a una instancia de objeto y vuelve a entrar en una secuencia XML.
Algunas sobrecargas del constructor del DataContractSerializer
tienen un parámetro ignoreExtensionDataObject
, que está establecido de forma predeterminada en false
. En este modo predeterminado, los datos se pueden enviar en un recorrido de ida y vuelta desde una versión más reciente de un contrato de datos a través de una versión anterior y volver a la versión más reciente sin pérdida, siempre y cuando el contrato de datos implemente la IExtensibleDataObject interfaz. Por ejemplo, supongamos que la versión 1 del Person
contrato de datos contiene los miembros de datos Name
y PhoneNumber
, y que la versión 2 agrega un miembro de datos Nickname
. Si IExtensibleDataObject
se implementa, al enviar información de la versión 2 a la versión 1, los Nickname
datos se almacenan y, a continuación, se vuelven a emitir cuando los datos se serializan de nuevo; por lo tanto, no se pierde ningún dato en el recorrido de ida y vuelta. Para obtener más información, consulte Forward-Compatible Contratos de Datos y Control de Versiones del Contrato de Datos.
Aspectos a tener en cuenta sobre seguridad y validez del esquema en relación con los viajes de ida y vuelta (round trip)
Los viajes de ida y vuelta pueden tener implicaciones de seguridad. Por ejemplo, deserializar y almacenar grandes cantidades de datos extraños puede ser un riesgo de seguridad. Puede haber problemas de seguridad sobre la re-emisión de estos datos que no hay ninguna manera de comprobar, especialmente si las firmas digitales están implicadas. Por ejemplo, en el escenario anterior, el punto de conexión de la versión 1 podría firmar un Nickname
valor que contenga datos malintencionados. Por último, puede haber problemas de validez del esquema: es posible que un punto de conexión quiera emitir siempre datos que se ajusten estrictamente a su contrato indicado y no a ningún valor adicional. En el ejemplo anterior, el contrato del punto de conexión de la versión 1 indica que emite solo Name
y PhoneNumber
, y si se usa la validación del esquema, la emisión del valor adicional Nickname
hace que se produzca un error en la validación.
Habilitar y deshabilitar los viajes de ida y vuelta
Para desactivar los recorridos de ida y vuelta, no implemente la IExtensibleDataObject interfaz . Si no tiene control sobre los tipos, establezca el ignoreExtensionDataObject
parámetro en true
para lograr el mismo efecto.
Conservación del gráfico de objetos
Normalmente, el serializador no se preocupa por la identidad del objeto, como en el código siguiente.
[DataContract]
public class PurchaseOrder
{
[DataMember]
public Address billTo;
[DataMember]
public Address shipTo;
}
[DataContract]
public class Address
{
[DataMember]
public string street;
}
<DataContract()> _
Public Class PurchaseOrder
<DataMember()> _
Public billTo As Address
<DataMember()> _
Public shipTo As Address
End Class
<DataContract()> _
Public Class Address
<DataMember()> _
Public street As String
End Class
El código siguiente crea un pedido de compra.
// Construct a purchase order:
Address adr = new Address();
adr.street = "123 Main St.";
PurchaseOrder po = new PurchaseOrder();
po.billTo = adr;
po.shipTo = adr;
' Construct a purchase order:
Dim adr As New Address()
adr.street = "123 Main St."
Dim po As New PurchaseOrder()
po.billTo = adr
po.shipTo = adr
Observe que los campos billTo
y shipTo
se establecen en la misma instancia de objeto. Sin embargo, el XML generado duplica la información duplicada y tiene un aspecto similar al siguiente XML.
<PurchaseOrder>
<billTo><street>123 Main St.</street></billTo>
<shipTo><street>123 Main St.</street></shipTo>
</PurchaseOrder>
Sin embargo, este enfoque tiene las siguientes características, que pueden no ser deseables:
Rendimiento. La replicación de datos es ineficaz.
Referencias circulares. Si los objetos se refieren a sí mismos, incluso a través de otros objetos, la serialización por replicación da como resultado un bucle infinito. (Si esto sucede, el serializador inicia una SerializationException .)
Semántica. A veces es importante conservar el hecho de que dos referencias son al mismo objeto y no a dos objetos idénticos.
Por estos motivos, algunas DataContractSerializer
sobrecargas de constructor tienen un preserveObjectReferences
parámetro (el valor predeterminado es false
). Cuando este parámetro se establece en true
, se utiliza un método especial de codificación de referencias de objeto que solo entiende WCF. Cuando se establece en true
, el ejemplo de código XML ahora es similar al siguiente.
<PurchaseOrder ser:id="1">
<billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>
<shipTo ser:ref="2"/>
</PurchaseOrder>
El espacio de nombres "ser" hace referencia al espacio de nombres de serialización estándar, http://schemas.microsoft.com/2003/10/Serialization/
. Cada fragmento de datos se serializa solo una vez y se da un número de identificador, y los usos posteriores dan como resultado una referencia a los datos ya serializados.
Importante
Si los atributos "id" y "ref" están presentes en el contrato XMLElement
de datos, se respeta el atributo "ref" y se omite el atributo "id".
Es importante comprender las limitaciones de este modo:
El XML que
DataContractSerializer
genera conpreserveObjectReferences
establecido entrue
no es interoperable con ninguna otra tecnología y solo puede ser accedido por otra instancia deDataContractSerializer
, también conpreserveObjectReferences
establecido entrue
.No hay compatibilidad con metadatos (esquema) para esta característica. El esquema generado solo es válido para el caso cuando
preserveObjectReferences
se establece enfalse
.Esta característica puede hacer que el proceso de serialización y deserialización se ejecute más lentamente. Aunque los datos no tienen que replicarse, se deben realizar comparaciones de objetos adicionales en este modo.
Precaución
Cuando se habilita el modo preserveObjectReferences
, es especialmente importante establecer el valor maxItemsInObjectGraph
en la cuota correcta. Debido a la manera en la que se administran las matrices en este modo, es fácil que un atacante construya un pequeño mensaje malintencionado que provoque un uso de memoria grande limitado únicamente por la cuota maxItemsInObjectGraph
.
Especificar un suplente de contrato de datos
Algunas DataContractSerializer
sobrecargas de constructor tienen un parámetro dataContractSurrogate
, que se puede establecer en null
. De lo contrario, puede utilizarlo para especificar un contrato de datos suplente, que es un tipo que implementa la interfaz IDataContractSurrogate . A continuación, puede usar la interfaz para personalizar el proceso de serialización y deserialización. Para obtener más información, consulte Representantes del contrato de datos.
Serialización
La siguiente información se aplica a cualquier clase que herede de XmlObjectSerializer, incluidas las DataContractSerializer clases y NetDataContractSerializer .
Serialización simple
La manera más básica de serializar un objeto es pasarlo al WriteObject método . Hay tres sobrecargas, que permiten escribir en una Stream, un XmlWritero un XmlDictionaryWriter. Con la sobrecarga Stream , el resultado es XML en la codificación UTF-8. Con la sobrecarga XmlDictionaryWriter , el serializador optimiza su resultado para XML binario.
Cuando se usa el WriteObject método , el serializador usa el nombre predeterminado y el espacio de nombres para el elemento contenedor y lo escribe junto con el contenido (vea la sección anterior "Especificar el nombre raíz predeterminado y el espacio de nombres").
En el ejemplo siguiente se muestra cómo escribir con un XmlDictionaryWriter.
Person p = new Person();
DataContractSerializer dcs =
new DataContractSerializer(typeof(Person));
XmlDictionaryWriter xdw =
XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 );
dcs.WriteObject(xdw, p);
Dim p As New Person()
Dim dcs As New DataContractSerializer(GetType(Person))
Dim xdw As XmlDictionaryWriter = _
XmlDictionaryWriter.CreateTextWriter(someStream, Encoding.UTF8)
dcs.WriteObject(xdw, p)
Esto produce XML similar al siguiente.
<Person>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Serialización paso a paso
Use los WriteStartObjectmétodos , WriteObjectContenty WriteEndObject para escribir el elemento final, escribir el contenido del objeto y cerrar el elemento contenedor, respectivamente.
Nota:
No hay ninguna sobrecarga Stream de estos métodos.
Esta serialización paso a paso tiene dos usos comunes. Uno es insertar contenido como atributos o comentarios entre WriteStartObject
y WriteObjectContent
, como se muestra en el ejemplo siguiente.
dcs.WriteStartObject(xdw, p);
xdw.WriteAttributeString("serializedBy", "myCode");
dcs.WriteObjectContent(xdw, p);
dcs.WriteEndObject(xdw);
dcs.WriteStartObject(xdw, p)
xdw.WriteAttributeString("serializedBy", "myCode")
dcs.WriteObjectContent(xdw, p)
dcs.WriteEndObject(xdw)
Esto produce XML similar al siguiente.
<Person serializedBy="myCode">
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Otro uso común es evitar usar WriteStartObject y WriteEndObject por completo, y escribir tu propio elemento contenedor personalizado (o incluso omitir el escribir un contenedor por completo), como se muestra en el código a continuación.
xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
xdw.WriteStartElement("MyCustomWrapper")
dcs.WriteObjectContent(xdw, p)
xdw.WriteEndElement()
Esto produce XML similar al siguiente.
<MyCustomWrapper>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</MyCustomWrapper>
Nota:
El uso de la serialización paso a paso puede dar lugar a XML no válido para el esquema.
Deserialización
La siguiente información se aplica a cualquier clase que herede de XmlObjectSerializer, incluidas las DataContractSerializer clases y NetDataContractSerializer .
La manera más básica de deserializar un objeto consiste en llamar a una de las sobrecargas del método ReadObject . Hay tres sobrecargas, que permiten leer con un XmlDictionaryReader, un XmlReader
o una Stream
. Tenga en cuenta que la Stream
sobrecarga crea un texto XmlDictionaryReader que no está protegido por ninguna cuota y solo se debe usar para leer datos de confianza.
También tenga en cuenta que el objeto que devuelve el método ReadObject
debe convertirse al tipo adecuado.
El siguiente código construye una instancia de DataContractSerializer y de XmlDictionaryReader, y a continuación deserializa una instancia de Person
.
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
Person p = (Person)dcs.ReadObject(reader);
Dim dcs As New DataContractSerializer(GetType(Person))
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = _
XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())
Dim p As Person = CType(dcs.ReadObject(reader), Person)
Antes de llamar al ReadObject método , coloque el lector XML en el elemento contenedor o en un nodo que no sea de contenido que precede al elemento contenedor. Puede hacerlo llamando al método Read de XmlReader o su derivación y probando el NodeType, como se muestra en el código siguiente.
DataContractSerializer ser = new DataContractSerializer(typeof(Person),
"Customer", @"http://www.contoso.com");
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (ser.IsStartObject(reader))
{
Console.WriteLine("Found the element");
Person p = (Person)ser.ReadObject(reader);
Console.WriteLine($"{p.Name} {p.Address} id:{2}");
}
Console.WriteLine(reader.Name);
break;
}
}
Dim ser As New DataContractSerializer(GetType(Person), "Customer", "http://www.contoso.com")
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())
While reader.Read()
Select Case reader.NodeType
Case XmlNodeType.Element
If ser.IsStartObject(reader) Then
Console.WriteLine("Found the element")
Dim p As Person = CType(ser.ReadObject(reader), Person)
Console.WriteLine("{0} {1}", _
p.Name, p.Address)
End If
Console.WriteLine(reader.Name)
End Select
End While
Observe que puede leer atributos en este elemento contenedor antes de entregar el lector a ReadObject
.
Cuando se usa una de las sobrecargas simples ReadObject
, el deserializador busca el nombre y el espacio de nombres predeterminados en el elemento contenedor (vea la sección anterior, "Especificar el nombre raíz predeterminado y el espacio de nombres") y produce una excepción si encuentra un elemento desconocido. En el ejemplo anterior, se espera el elemento contenedor <Person>
. Se llamará al método IsStartObject para comprobar que el lector esté posicionado en un elemento nombrado según lo esperado.
Hay una manera de deshabilitar esta comprobación del nombre del elemento contenedor; algunas sobrecargas del método ReadObject
toman el parámetro verifyObjectName
booleano, que se establece de forma predeterminada en true
. Cuando se establece en false
, se omite el nombre y el espacio de nombres del elemento contenedor. Esto es útil para leer XML que se escribió mediante el mecanismo de serialización paso a paso descrito anteriormente.
Uso de NetDataContractSerializer
La principal diferencia entre DataContractSerializer
y NetDataContractSerializer es que DataContractSerializer
usa nombres de contrato de datos, mientras que NetDataContractSerializer
genera nombres completos de ensamblado y tipo de .NET Framework en el XML serializado. Esto significa que se han de compartir exactamente los mismos tipos entre los extremos de serialización y deserialización. Esto significa que el mecanismo de tipos conocidos no es necesario con NetDataContractSerializer
porque siempre se conocen los tipos exactos que se van a deserializar.
Sin embargo, pueden producirse varios problemas:
Seguridad. Se carga cualquier tipo en el XML que se esté deserializando. Esto se puede explotar para forzar la carga de tipos malintencionados. El uso del
NetDataContractSerializer
con datos que no son de confianza solo se debería realizar si se utiliza un Enlazador de Serialización (mediante el parámetro del constructor o la propiedad Binder ). El enlazador solo permite cargar tipos seguros. El mecanismo del enlazador es idéntico al que utilizan los tipos en el espacio de nombres de System.Runtime.Serialization .Control de versiones El uso de nombres de ensamblado y de tipo completo en el XML restringe gravemente cómo se pueden crear versiones de los tipos. No se puede cambiar lo siguiente: nombres de tipo, espacios de nombres, nombres de ensamblado y versiones de ensamblado. Establecer la propiedad o el parámetro de constructor AssemblyFormat en Simple en lugar del valor predeterminado de Full permite cambios en la versión del ensamblado, pero no para los tipos de parámetro genéricos.
Interoperabilidad. Dado que los nombres de ensamblado y tipo de .NET Framework se incluyen en el XML, las plataformas distintas de .NET Framework no pueden tener acceso a los datos resultantes.
Rendimiento. La escritura de los nombres de tipo y ensamblado aumenta significativamente el tamaño del XML resultante.
Este mecanismo es similar a la serialización binaria o de SOAP utilizada por la comunicación remota de .NET Framework (específicamente, BinaryFormatter y SoapFormatter).
Usar el NetDataContractSerializer
es similar a usar el DataContractSerializer
, con las siguientes diferencias:
Los constructores no requieren que especifique un tipo de raíz. Puede serializar cualquier tipo con la misma instancia del
NetDataContractSerializer
.Los constructores no aceptan una lista de tipos conocidos. El mecanismo de tipos conocidos no es necesario si los nombres de tipo se serializan en el XML.
Los constructores no aceptan un contrato de datos suplente. En su lugar, aceptan un parámetro ISurrogateSelector llamado
surrogateSelector
(que se asigna a la propiedad SurrogateSelector). Se trata de un mecanismo suplente heredado.Los constructores aceptan un parámetro llamado
assemblyFormat
del FormatterAssemblyStyle que se asigna a la propiedad AssemblyFormat. Como se explicó anteriormente, esto se puede usar para mejorar las funcionalidades de control de versiones del serializador. Esto es idéntico al mecanismo FormatterAssemblyStyle de serialización binaria o de SOAP.Los constructores aceptan un StreamingContext parámetro denominado
context
que se asigna a la propiedad Context. Puede utilizar esto para pasar información en los tipos que se serializan. Este uso es idéntico al del StreamingContext mecanismo usado en otras System.Runtime.Serialization clases.Los Serialize métodos y Deserialize son alias para los WriteObject métodos y ReadObject . Existen para proporcionar un modelo de programación más coherente con la serialización binaria o SOAP.
Para obtener más información sobre estas características, vea Serialización binaria.
Los formatos XML que NetDataContractSerializer
y el DataContractSerializer
uso normalmente no son compatibles. Es decir, intentar serializar con uno de estos serializadores y deserializar con el otro no es un escenario admitido.
Además, tenga en cuenta que NetDataContractSerializer
no genera el tipo completo de .NET Framework y el nombre del ensamblado para cada nodo del gráfico de objetos. Genera esa información solo donde es ambigua. Es decir, produce el resultado en el nivel del objeto raíz y para cualquier caso polimórfico.