Tipos de XML e ADO.NET em contratos de dados
O modelo de contrato de dados do WCF (Windows Communication Foundation) permite determinados tipos que representam o XML diretamente. Quando esses tipos são serializados para XML, o serializador grava o conteúdo XML desses tipos sem nenhum processamento adicional. Os tipos compatíveis são XmlElement, matrizes XmlNode (mas não do tipo XmlNode
em si), bem como tipos que implementam IXmlSerializable. O tipo DataSet e DataTable, bem como conjuntos de dados tipado, são comumente usados na programação de banco de dados. Esses tipos implementam a interface IXmlSerializable
e, portanto, são serializáveis no modelo de contrato de dados. Algumas considerações especiais para esses tipos são listadas no final deste tópico.
Tipos XML
Elemento XML
O tipo XmlElement
é serializado usando seu conteúdo XML. Por exemplo, usando o tipo a seguir.
[DataContract(Namespace=@"http://schemas.contoso.com")]
public class MyDataContract
{
[DataMember]
public XmlElement myDataMember;
public void TestClass()
{
XmlDocument xd = new XmlDocument();
myDataMember = xd.CreateElement("myElement");
myDataMember.InnerText = "myContents";
myDataMember.SetAttribute
("myAttribute","myValue");
}
}
<DataContract([Namespace]:="http://schemas.contoso.com")> _
Public Class MyDataContract
<DataMember()> _
Public myDataMember As XmlElement
Public Sub TestClass()
Dim xd As New XmlDocument()
myDataMember = xd.CreateElement("myElement")
myDataMember.InnerText = "myContents"
myDataMember.SetAttribute("myAttribute", "myValue")
End Sub
End Class
Isso é serializado para XML da seguinte maneira:
<MyDataContract xmlns="http://schemas.contoso.com">
<myDataMember>
<myElement xmlns="" myAttribute="myValue">
myContents
</myElement>
</myDataMember>
</MyDataContract>
Observe que um elemento <myDataMember>
de membro de dados wrapper ainda está presente. Não há como remover esse elemento no modelo de contrato de dados. Os serializadores que manipulam esse modelo (o DataContractSerializer e NetDataContractSerializer) podem emitir atributos especiais nesse elemento wrapper. Esses atributos incluem o atributo padrão da Instância de Esquema XML "zero" (permitindo que XmlElement
seja null
) e o atributo "type" (permitindo que XmlElement
seja usado polimorficamente). Além disso, os seguintes atributos XML são específicos do WCF: "Id", "Ref", "Type" e "Assembly". Esses atributos podem ser emitidos para permitir o uso de XmlElement
com o modo de preservação do grafo de objetos habilitado ou com o NetDataContractSerializer. (Para obter mais informações sobre o modo de preservação do grafo de objeto, consulte Serialização e Desserialização.)
Matrizes ou coleções de XmlElement
são permitidas e são tratadas como qualquer outra matriz ou coleção. Ou seja, há um elemento wrapper para toda a coleção e um elemento wrapper separado (semelhante ao <myDataMember>
exemplo anterior) para cada XmlElement
na matriz.
Na desserialização, um XmlElement
é criado pelo desserializador do XML de entrada. Um pai XmlDocument válido é fornecido pelo desserializador.
Verifique se o fragmento XML desserializado para um XmlElement
define todos os prefixos que ele usa e não depende de nenhuma definição de prefixo de elementos ancestrais. Essa é uma preocupação somente ao usar o DataContractSerializer
para acessar o XML de uma origem diferente (não DataContractSerializer
).
Quando usado com o DataContractSerializer
, o XmlElement
pode ser atribuído polimorficamente, mas apenas a um membro de dados do tipo Object. Mesmo que ele implemente IEnumerable, um XmlElement
não pode ser usado como um tipo de coleção e não pode ser atribuído a um membro de dados IEnumerable. Assim como acontece com todas as atribuições polimórficas, o DataContractSerializer
emite o contrato de dados no XML resultante. Nesse caso, é "XmlElement" no namespace http://schemas.datacontract.org/2004/07/System.Xml
.
Com NetDataContractSerializer
, qualquer atribuição polimórfica válida de XmlElement
(para Object
ou IEnumerable
) é compatível.
Não tente usar nenhum dos serializadores com tipos derivados de XmlElement
, sejam eles atribuídos polimorficamente ou não.
Matriz de XmlNode
Usar matrizes de XmlNode é muito semelhante a usar XmlElement
. Usar matrizes de XmlNode
oferece mais flexibilidade do que usar XmlElement
. Você pode escrever vários elementos dentro do elemento de encapsulamento do membro de dados. Você também pode injetar conteúdo diferente de elementos dentro do elemento de encapsulamento do membro de dados, como comentários XML. Por fim, você pode colocar atributos no elemento de membro de dados de encapsulamento. Tudo isso pode ser obtido preenchendo a matriz de XmlNode
com classes derivadas específicas de XmlNode
, como XmlAttribute, XmlElement
ou XmlComment. Por exemplo, usando o tipo a seguir.
[DataContract(Namespace="http://schemas.contoso.com")]
public class MyDataContract
{
[DataMember]
public XmlNode[] myDataMember = new XmlNode[4];
public void TestClass()
{
XmlDocument xd = new XmlDocument();
XmlElement xe = xd.CreateElement("myElement");
xe.InnerText = "myContents";
xe.SetAttribute
("myAttribute","myValue");
XmlAttribute atr = xe.Attributes[0];
XmlComment cmnt = xd.CreateComment("myComment");
myDataMember[0] = atr;
myDataMember[1] = cmnt;
myDataMember[2] = xe;
myDataMember[3] = xe;
}
}
<DataContract([Namespace]:="http://schemas.contoso.com")> _
Public Class MyDataContract
<DataMember()> _
Public myDataMember(3) As XmlNode
Public Sub TestClass()
Dim xd As New XmlDocument()
Dim xe As XmlElement = xd.CreateElement("myElement")
xe.InnerText = "myContents"
xe.SetAttribute("myAttribute", "myValue")
Dim atr As XmlAttribute = xe.Attributes(0)
Dim cmnt As XmlComment = xd.CreateComment("myComment")
myDataMember(0) = atr
myDataMember(1) = cmnt
myDataMember(2) = xe
myDataMember(3) = xe
End Sub
End Class
Quando serializado, o XML resultante é semelhante ao código a seguir.
<MyDataContract xmlns="http://schemas.contoso.com">
<myDataMember myAttribute="myValue">
<!--myComment-->
<myElement xmlns="" myAttribute="myValue">
myContents
</myElement>
<myElement xmlns="" myAttribute="myValue">
myContents
</myElement>
</myDataMember>
</MyDataContract>
Observe que o <myDataMember>
do elemento wrapper do membro de dados contém um atributo, um comentário e dois elementos. Estas são as quatro instâncias XmlNode
que foram serializadas.
Uma matriz de XmlNode
resulta em XML inválido não pode ser serializado. Por exemplo, uma matriz de duas instâncias XmlNode
, em que a primeira é um XmlElement
e a segunda é um XmlAttribute inválido, pois essa sequência não corresponde a nenhuma instância XML válida (não há lugar para anexar o atributo).
Na desserialização de uma matriz de XmlNode
, os nós são criados e preenchidos com informações do XML de entrada. Um pai XmlDocument válido é fornecido pelo desserializador. Todos os nós são desserializados, incluindo todos os atributos no elemento membro de dados wrapper, mas excluindo os atributos colocados lá pelos serializadores do WCF (como os atributos usados para indicar a atribuição polimórfica). A restrição sobre a definição de todos os prefixos de namespace no fragmento XML se aplica à desserialização de matrizes de XmlNode
, da mesma forma que faz para desserializar XmlElement
.
Ao usar os serializadores com a preservação do grafo de objeto ativada, a igualdade de objetos só é preservada no nível das matrizes XmlNode
, não em instâncias individuais XmlNode
.
Não tente serializar uma matriz de XmlNode
, em um ou mais nós estão definidos como null
. É permitido que todo o membro da matriz seja null
, mas não para qualquer XmlNode
individual contido na matriz. Se todo o membro da matriz for nulo, o elemento membro de dados wrapper conterá um atributo especial que indica que ele é nulo. Na desserialização, todo o membro da matriz também se torna nulo.
Somente matrizes regulares de XmlNode
são tratadas especialmente pelo serializador. Os membros de dados declarados como outros tipos de coleção que contêm XmlNode
, ou membros de dados declarados como matrizes de tipos derivados de XmlNode
, não são tratados especialmente. Portanto, eles normalmente não são serializáveis, a menos que também atendam a um dos outros critérios para serialização.
Matrizes ou coleções de matrizes de XmlNode
são permitidas. Há um elemento wrapper para toda a coleção e um elemento wrapper separado (semelhante ao <myDataMember>
no exemplo anterior) para cada matriz de XmlNode
na matriz externa ou coleção.
Preencher um membro de dados do tipo Array de Object
ou Array
de IEnumerable
com instâncias XmlNode
não resulta no membro de dados sendo tratado como instâncias Array
de XmlNode
. Cada membro da matriz é serializado separadamente.
Quando usado com o DataContractSerializer
, as matrizes de XmlNode
podem ser atribuídas polimorficamente, mas apenas a um membro de dados do tipo Object
. Mesmo que ela implemente IEnumerable
, uma matriz de XmlNode
não pode ser usada como um tipo de coleção nem ser atribuída a um membro de dados IEnumerable
. Assim como acontece com todas as atribuições polimórficas, o DataContractSerializer
emite o contrato de dados no XML resultante – nesse caso, é "XmlElement" no namespace http://schemas.datacontract.org/2004/07/System.Xml
. Quando usado com o NetDataContractSerializer
, qualquer atribuição válida de uma matriz XmlNode
é compatível.
Considerações sobre esquema
Para obter detalhes sobre o mapeamento de esquema de tipos XML, consulte Referência de esquema de contrato de dados. Esta seção fornece um resumo dos pontos importantes.
Um membro de dados do tipo XmlElement
é mapeado para um elemento definido usando o tipo anônimo a seguir.
<xsd:complexType>
<xsd:sequence>
<xsd:any minOccurs="0" processContents="lax" />
</xsd:sequence>
</xsd:complexType>
Um membro de dados da matriz do tipo XmlNode
é mapeado para um elemento definido usando o tipo anônimo a seguir.
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
Tipos que implementam a interface IXmlSerialable
Os tipos que implementam a interface IXmlSerializable
têm compatibilidade total pelo DataContractSerializer
. O atributo XmlSchemaProviderAttribute deve ser sempre aplicado a esses tipos para controlar seu esquema.
Há três variedades de tipos que implementam IXmlSerializable
: tipos que representam conteúdo arbitrário, tipos que representam um único elemento e tipos DataSet herdados.
Os tipos de conteúdo usam um método de provedor de esquema especificado pelo atributo
XmlSchemaProviderAttribute
. O método não retornanull
e a propriedade IsAny no atributo é deixada no valor padrão defalse
. Esse é o uso mais comum de tiposIXmlSerializable
.Os tipos de elemento são usados quando um tipo
IXmlSerializable
precisa controlar seu próprio nome de elemento raiz. Para marcar um tipo como um tipo de elemento, defina a propriedade IsAny no atributo XmlSchemaProviderAttribute comotrue
ou retorne nulo do método do provedor de esquema. Ter um método de provedor de esquema é opcional para tipos de elemento. Você pode especificar nulo em vez do nome do método noXmlSchemaProviderAttribute
. No entanto, seIsAny
fortrue
e um método de provedor de esquema for especificado, o método deverá retornar nulo.Tipos herdados DataSet são tipos
IXmlSerializable
que não são marcados com o atributoXmlSchemaProviderAttribute
. Em vez disso, eles dependem do método GetSchema para geração de esquema. Esse padrão é usado para o tipoDataSet
e seu conjunto de dados tipado deriva uma classe em versões anteriores do .NET Framework, mas agora está obsoleto e tem compatibilidade apenas por motivos herdados. Não confie nesse padrão e sempre aplique oXmlSchemaProviderAttribute
aos seus tiposIXmlSerializable
.
Tipos de conteúdo IXmlSerializable
Ao serializar um membro de dados de um tipo que implementa IXmlSerializable
e é um tipo de conteúdo conforme definido anteriormente, o serializador grava o elemento wrapper para o membro de dados e passa o controle para o método WriteXml. A implementação de WriteXml pode gravar qualquer XML, incluindo a adição de atributos ao elemento wrapper. Depois que WriteXml
é concluído, o serializador fecha o elemento.
Ao desserializar um membro de dados de um tipo que implementa IXmlSerializable
e é um tipo de conteúdo conforme definido anteriormente, o desserializador posiciona o leitor XML no elemento wrapper para o membro de dados e passa o controle para o método ReadXml. O método precisa ler todo o elemento, incluindo as marcas inicial e final. Verifique se o código ReadXml
manipula o caso em que o elemento está vazio. Além disso, sua implementação de ReadXml
não deve depender do elemento wrapper que está sendo nomeado de uma maneira específica. O nome escolhido pelo serializador pode variar.
É permitido atribuir tipos de conteúdo IXmlSerializable
polimorficamente, por exemplo, a membros de dados do tipo Object. Também é permitido que as instâncias de tipo sejam nulas. Por fim, é possível usar tipos IXmlSerializable
com a preservação do grafo de objeto habilitada e com o NetDataContractSerializer. Todos esses recursos exigem que o serializador WCF anexe determinados atributos ao elemento wrapper ("nil" e "type" no namespace da Instância de Esquema XML e "Id", "Ref", "Type" e "Assembly" em um namespace específico do WCF).
Atributos a serem ignorados ao implementar ReadXml
Antes de passar o controle para o código ReadXml
, o desserializador examina o elemento XML, detecta esses atributos XML especiais e atua neles. Por exemplo, se "nil" for true
, um valor nulo será desserializado e ReadXml
não será chamado. Se o polimorfismo for detectado, o conteúdo do elemento será desserializado como se fosse um tipo diferente. A implementação do tipo atribuído polimorficamente de ReadXml
é chamada. De qualquer forma, uma implementação ReadXml
deve ignorar esses atributos especiais porque eles são tratados pelo desserializador.
Considerações de esquema para tipos de conteúdo IXmlSerializable
Ao exportar o esquema de um tipo de conteúdo IXmlSerializable
, o método do provedor de esquema é chamado. Um XmlSchemaSet é passado para o método do provedor de esquema. O método pode adicionar qualquer esquema válido ao conjunto de esquemas. O conjunto de esquemas contém o esquema que já é conhecido no momento em que ocorre a exportação de esquema. Quando o método do provedor de esquema precisa adicionar um item ao conjunto de esquemas, ele precisa determinar se já existe um XmlSchema com o namespace apropriado no conjunto. Se isso acontecer, o método do provedor de esquema precisa adicionar o novo item ao XmlSchema
existente. Caso contrário, ele precisa criar uma nova instância XmlSchema
. Isso é importante se matrizes de tipos IXmlSerializable
estiverem sendo usadas. Por exemplo, se você tiver um tipo IXmlSerializable
exportado como tipo "A" no namespace "B", é possível que, quando o método do provedor de esquema for chamado, o esquema já contenha o esquema de "B" para manter o tipo "ArrayOfA".
Além de adicionar tipos ao XmlSchemaSet, o método de provedor de esquema para tipos de conteúdo precisa retornar um valor não nulo. Ele pode retornar um XmlQualifiedName que especifica o nome do tipo de esquema a ser usado para o tipo IXmlSerializable
fornecido. Esse nome qualificado também serve como o nome e o namespace do contrato de dados para o tipo. É permitido retornar um tipo que não existe no esquema definido imediatamente quando o método do provedor de esquema retorna. No entanto, espera-se que, quando todos os tipos relacionados forem exportados (o método Export é chamado para todos os tipos relevantes no XsdDataContractExporter e a Schemas propriedade é acessada), o tipo exista no conjunto de esquemas. Acessar a propriedade Schemas
antes que todas as chamadas Export
relevantes tenham sido feitas pode resultar em um XmlSchemaException. Para obter mais informações sobre o processo de exportação, consulte Exportando esquemas de classes.
O método do provedor de esquema também pode retornar o XmlSchemaType para usar. O tipo pode ou não ser anônimo. Se for anônimo, o esquema do tipo IXmlSerializable
será exportado como um tipo anônimo sempre que o tipo IXmlSerializable
for usado como membro de dados. O tipo IXmlSerializable
ainda tem um namespace e um nome de contrato de dados. (Isso é determinado conforme descrito em Nomes de Contrato de Dados , exceto que o atributo DataContractAttribute não pode ser usado para personalizar o nome.) Se não for anônimo, ele precisará ser um dos tipos no XmlSchemaSet
. Esse caso é equivalente a retornar o XmlQualifiedName
do tipo.
Além disso, uma declaração de elemento global é exportada para o tipo. Se o tipo não tiver o atributo XmlRootAttribute aplicado a ele, o elemento terá o mesmo nome e namespace que o contrato de dados e sua propriedade "nillable" será true
. A única exceção a isso é o namespace de esquema (http://www.w3.org/2001/XMLSchema
). Se o contrato de dados do tipo estiver nesse namespace, o elemento global correspondente estará no namespace em branco porque é proibido adicionar novos elementos ao namespace de esquema. Se o tipo tiver o atributo XmlRootAttribute
aplicado a ele, a declaração de elemento global será exportada usando as seguintes propriedades: ElementName, Namespace e IsNullable. Os padrões com XmlRootAttribute
aplicados são o nome do contrato de dados, um namespace em branco e "nillable" sendo verdadeiro.
As mesmas regras de declaração de elemento global se aplicam aos tipos de conjunto de dados herdados. Observe que não é possível substituir declarações XmlRootAttribute
de elemento global adicionadas por meio de código personalizado, adicionadas ao XmlSchemaSet
usando o método de provedor de esquema ou por meio de GetSchema
para tipos de conjunto de dados herdados.
Tipos de elemento IXmlSerializable
os tipos de elemento IXmlSerializable
têm a propriedade IsAny
definida como true
ou têm o método de provedor de esquema retornado null
.
Serializar e desserializar um tipo de elemento é muito semelhante à serialização e desserialização de um tipo de conteúdo. No entanto há algumas diferenças importantes:
Espera-se que a implementação de
WriteXml
grave exatamente um elemento (que, naturalmente, poderia conter vários elementos filho). Ele não deve escrever atributos fora desse único elemento, vários elementos irmãos ou conteúdo misto. O elemento pode estar vazio.A implementação de
ReadXml
não deve ler o elemento wrapper. Espera-se que ele leia o único elemento queWriteXml
produz.Ao serializar um tipo de elemento regularmente (por exemplo, como um membro de dados em um contrato de dados), o serializador gera um elemento wrapper antes de chamar
WriteXml
, como acontece com os tipos de conteúdo. No entanto, ao serializar um tipo de elemento no nível superior, o serializador normalmente não gera um elemento wrapper em torno do elemento queWriteXml
grava, a menos que um nome raiz e namespace tenham sido explicitamente especificados ao construir o serializador nos construtoresDataContractSerializer
ouNetDataContractSerializer
. Para obter mais informações, consulte Serialização e Desserialização.Ao serializar um tipo de elemento no nível superior sem especificar o nome raiz e o namespace em tempo de construção, WriteStartObject e WriteEndObject essencialmente não fazem nada e WriteObjectContent chama
WriteXml
. Nesse modo, o objeto que está sendo serializado não pode ser nulo e não pode ser atribuído polimorficamente. Além disso, a preservação do grafo de objeto não pode ser habilitada e nãoNetDataContractSerializer
pode ser usado.Ao desserializar um tipo de elemento no nível superior sem especificar o nome raiz e o namespace em tempo de construção, IsStartObject retornará
true
se ele puder encontrar o início de qualquer elemento. ReadObject com o parâmetro definidoverifyObjectName
paratrue
se comporta da mesma maneira queIsStartObject
antes de realmente ler o objeto.ReadObject
, em seguida, passa o controle para o métodoReadXml
.
O esquema exportado para tipos de elemento é o mesmo que para o tipo XmlElement
descrito em uma seção anterior, exceto que o método do provedor de esquema pode adicionar qualquer esquema adicional ao XmlSchemaSet como tipo de conteúdo. O uso do atributo XmlRootAttribute
com tipos de elemento não é permitido, e declarações de elemento global nunca são emitidas para esses tipos.
Diferenças do XmlSerializer
A interface IXmlSerializable
e os atributos XmlSchemaProviderAttribute
e XmlRootAttribute
são também reconhecidos pelo XmlSerializer. No entanto, há algumas diferenças na forma como elas são tratadas no modelo de contrato de dados. As diferenças importantes estão resumidas a seguir:
O método do provedor de esquema precisa ser público para ser utilizável no
XmlSerializer
, mas não no modelo de contrato de dados.O método do provedor de esquema é chamado quando
IsAny
é verdadeiro no modelo de contrato de dados, mas não com oXmlSerializer
.Quando o atributo
XmlRootAttribute
não está presente para tipos de conteúdo ou conjunto de dados herdados, oXmlSerializer
exporta uma declaração do elemento global no namespace em branco. No modelo de contrato de dados, o namespace usado normalmente é o namespace do contrato de dados, conforme descrito anteriormente.
Lembre-se dessas diferenças ao criar tipos usados com ambas as tecnologias de serialização.
Importando esquema IXmlSerializable
Ao importar um esquema gerado de tipos IXmlSerializable
, há algumas possibilidades:
O esquema gerado pode ser um esquema de contrato de dados válido, conforme descrito na Referência de Esquema de Contrato de Dados. Nesse caso, o esquema pode ser importado como de costume e tipos de contrato de dados regulares são gerados.
O esquema gerado pode não ser um esquema de contrato de dados válido. Por exemplo, seu método de provedor de esquema pode gerar um esquema que envolve atributos XML que não têm compatibilidade no modelo de contrato de dados. Nesse caso, você pode importar o esquema como tipos
IXmlSerializable
. Esse modo de importação não está ativado por padrão, mas pode ser facilmente habilitado – por exemplo, com a opção de linha de comando/importXmlTypes
para a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe). Isso é descrito em detalhes em Importando esquemas para gerar classes. Observe que você precisa trabalhar diretamente com o XML para suas instâncias de tipo. Você também pode considerar o uso de uma tecnologia de serialização diferente que permite uma gama mais ampla de esquemas. Veja o tópico sobre como usar oXmlSerializer
.Talvez você queira reutilizar seus tipos
IXmlSerializable
existentes no proxy em vez de gerar novos. Nesse caso, o recurso de tipos referenciados descrito no tópico “Importar esquema para gerar tipos” pode ser usado para indicar o tipo a ser reutilizado. Isso corresponde ao uso da opção/reference
no svcutil.exe, que especifica o assembly que contém os tipos a serem reutilizados.
Representando XML arbitrário em contratos de dados
O XmlElement
, a matriz XmlNode
e os tipos IXmlSerializable
permitem injetar XML arbitrário no modelo de contrato de dados. O DataContractSerializer
e NetDataContractSerializer
passam esse conteúdo XML para o gravador XML em uso, sem interferir no processo. No entanto, os gravadores XML podem impor determinadas restrições ao XML que eles gravam. Especificamente, veja alguns exemplos importantes:
Os gravadores XML normalmente não permitem uma declaração de documento XML (por exemplo, <?xml version='1.0' ?>) no meio da gravação de outro documento. Você não pode pegar um documento XML completo e serializá-lo como um
Array
do membro de dadosXmlNode
. Para fazer isso, você precisa remover a declaração do documento ou usar seu próprio esquema de codificação para representá-la.Todos os gravadores XML fornecidos com o WCF rejeitam instruções de processamento XML (<? ... ?>) e definições de tipo de documento (<! ... >), porque elas não são permitidas em mensagens SOAP. Novamente, você pode usar seu próprio mecanismo de codificação para contornar essa restrição. Se você precisar incluí-los no XML resultante, você poderá escrever um codificador personalizado que usa gravadores XML que permitem eles.
Ao implementar
WriteXml
, evite chamar o método WriteRaw no gravador XML. O WCF usa uma variedade de codificações XML (incluindo binária), é muito difícil ou impossível usarWriteRaw
de modo que o resultado seja utilizável em qualquer codificação.Ao implementar
WriteXml
, evite usar os métodos WriteEntityRef e WriteNmToken que não são compatíveis com os gravadores XML fornecidos com o WCF.
Usando DataSet, DataSet Digitado e DataTable
O uso desses tipos é totalmente compatível com o modelo de contrato de dados. Ao usar domínios personalizados, considere os seguintes pontos:
O esquema para esses tipos (especialmente DataSet e suas classes derivadas tipadas) pode não ser interoperável com algumas plataformas não WCF ou resultar em baixa usabilidade com essas plataformas. Além disso, o uso do tipo
DataSet
pode ter implicações de desempenho. Por fim, isso pode dificultar a versão do aplicativo no futuro. Considere usar tipos de contrato de dados explicitamente definidos em vez de tiposDataSet
nos seus contratos.Ao importar o esquema
DataSet
ouDataTable
, é importante fazer referência a esses tipos. Com a ferramenta de linha de comando Svcutil.exe, isso pode ser feito passando o nome do assembly System.Data.dll para a opção/reference
. Se estiver importando o esquema de conjunto de dados tipado, você deverá referenciá-lo. Com Svcutil.exe, passe o local do assembly do conjunto de dados tipado para a opção/reference
. Para obter mais informações sobre tipos de referência, consulte Importando esquema para gerar classes.
A compatibilidade para DataSets tipados no modelo de contrato de dados é limitada. DataSets tipoados podem ser serializados e desserializados e podem exportar seu esquema. No entanto, a importação de esquema do Contrato de Dados não pode gerar novos tipos de Conjunto de Dados tipado do esquema, pois ele só pode reutilizar os existentes. Você pode apontar para um DataSet tipado existente usando a opção /r
no Svcutil.exe. Se você tentar usar um Svcutil.exe sem a opção /r
em um serviço que usa um conjunto de dados tipado, um serializador alternativo (XmlSerializer) será selecionado automaticamente. Se você precisar usar o DataContractSerializer e gerar DataSets do esquema, poderá usar o seguinte procedimento: gerar os tipos de DataSets tipado (usando a ferramenta Xsd.exe com a opção /d
no serviço), compilar os tipos e, em seguida, apontá-los usando a opção /r
no Svcutil.exe.