Quando usar os atributos DataContract e DataMember?

179

Estou muito confuso sobre o DataContractatributo no WCF. De acordo com meu conhecimento, é usado para serializar tipos definidos pelo usuário, como classes. Eu escrevi uma classe que é exposta no lado do cliente assim.

[DataContract]
public class Contact
{
    [DataMember]
    public int Roll { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Address { get; set; }

    [DataMember]
    public int Age { get; set; }
}

Está funcionando corretamente, mas quando removo DataContracte DataMembertambém funciona corretamente. Não consigo entender por que está funcionando corretamente. Alguém pode me dizer qual é o uso real DataContract?

Meu contrato de serviço se parece com isso

[ServiceContract]    
public interface IRestServiceImpl
{
    [OperationContract]        
    Contact XmlData(string id);      
}
sam
fonte
A resposta perfeita é aqui stackoverflow.com/questions/5681842/...
Asif Iqbal

Respostas:

361

Como muitos programadores ficaram impressionados com os atributos [DataContract]e [DataMember], com o .NET 3.5 SP1, a Microsoft fez com que o serializador de contrato de dados lidasse com todas as classes - mesmo sem nenhum desses atributos -, como o antigo serializador XML.

Portanto, no .NET 3.5 SP1, você não precisa mais adicionar atributos de contrato ou membro de dados - caso contrário, o serializador de contrato de dados serializará todas as propriedades públicas da sua classe, como faria o serializador de XML.

NO ENTANTO: ao não adicionar esses atributos, você perde muitos recursos úteis:

  • sem [DataContract], você não pode definir um espaço para nome XML para seus dados residirem
  • sem [DataMember], você não pode serializar propriedades ou campos não públicos
  • sem [DataMember], você não pode definir uma ordem de serialização ( Order=) e o DCS serializará todas as propriedades em ordem alfabética
  • sem [DataMember], você não pode definir um nome diferente para sua propriedade ( Name=)
  • sem [DataMember], você não pode definir coisas como IsRequired=ou outros atributos úteis
  • sem [DataMember], você não pode excluir certas propriedades públicas - todas as propriedades públicas serão serializadas pelo DCS

Portanto, para uma solução "rápida e noventa", deixar de lado os atributos [DataContract]e [DataMember]funcionará - mas ainda é uma boa ideia incluí- los em suas classes de dados - apenas para ser mais explícito sobre o que você está fazendo e para se dar acesso a todos esses recursos adicionais que você não obtém sem eles ...

marc_s
fonte
por padrão, todos os tipos de dados são marcados internamente como serializáveis ​​e usamos o DataContract / DataMember para restringi-los.
Santosh Singh
2
@Santosh: se você tiver uma classe com algumas propriedades públicas, elas serão serializadas pelo serializador de contrato de dados do WCF, a menos que você aplique explicitamente [DataContract] / [DataMember] .-, então é 100% sua a responsabilidade de dizer o que é serializado e o que não é?
marc_s
36
@ Arthur: isso não é totalmente verdade. A partir do .NET 3.5 SP1, o WCF alegremente serializa classes sem nenhum atributo [DataContract]e [DataMember]... mas assim que você começar a usar um desses atributos, esse comportamento "padrão" deixará de funcionar - assim que você tiver um único [DataMember] no seu classe, a partir desse ponto, apenas as propriedades com esse atributo serão serializadas.
Marc #
4
Oohh! Agradecemos por esclarecer esse ponto! Então vou cavar um pouco mais!
Arthis
6
Youhou! Isso arrasa!! Merci beaucoup!
Arthis
16

Em termos de WCF, podemos nos comunicar com o servidor e o cliente através de mensagens. Para transferir mensagens e de um possível cliente de segurança, precisamos criar dados / mensagens em um formato serializado.

Para serializar dados, usamos os atributos [datacontract] e [datamember]. No seu caso, se você estiver usando o datacontractWCF, o WCF utilizará DataContractSerializeroutra, XmlSerializerque é a técnica de serialização padrão.

Deixe-me explicar em detalhes:

basicamente o WCF suporta 3 tipos de serialização:

  1. XmlSerializer
  2. DataContractSerializer
  3. NetDataContractSerializer

XmlSerializer : - A ordem padrão é igual à classe

DataContractSerializer / NetDataContractSerializer : - A ordem padrão é em ordem alfabética

XmlSerializer : - O esquema XML é extenso

DataContractSerializer / NetDataContractSerializer : - O esquema XML está restrito

XmlSerializer : - Suporte a versão não é possível

DataContractSerializer / NetDataContractSerializer : - O suporte à versão é possível

XmlSerializer : - Compatibilidade com ASMX

DataContractSerializer / NetDataContractSerializer : - Compatibilidade com o .NET Remoting

XmlSerializer : - Atributo não necessário no XmlSerializer

DataContractSerializer / NetDataContractSerializer : - Atributo necessário nesta serialização

então o que você usa depende de seus requisitos ...

Pradeep atkari
fonte
8

Um contrato de dados é um contrato formal entre um serviço e um cliente que descreve abstratamente os dados a serem trocados. Ou seja, para se comunicar, o cliente e o serviço não precisam compartilhar os mesmos tipos, apenas os mesmos contratos de dados. Um contrato de dados define com precisão, para cada parâmetro ou tipo de retorno, quais dados são serializados (transformados em XML) a serem trocados.

O Windows Communication Foundation (WCF) usa um mecanismo de serialização chamado Data Contract Serializer por padrão para serializar e desserializar dados (convertê-los para e do XML). Todos os tipos primitivos do .NET Framework, como números inteiros e seqüências de caracteres, bem como certos tipos tratados como primitivos, como DateTime e XmlElement, podem ser serializados sem outra preparação e são considerados como tendo contratos de dados padrão. Muitos tipos do .NET Framework também possuem contratos de dados existentes.

Você pode encontrar o artigo completo aqui.

mr.b
fonte
2
Isso é verdade e correto, mas não responde à pergunta do OP sobre por que o serializador de contrato de dados também funciona sem nenhum atributo [DataContract] e [DataMember] em suas classes ... #
31711
Alguém pode me dizer qual é o uso real do DataContract? - Acho que pelo menos parte da pergunta foi respondida.
IAbstract
2

Um contrato de dados é um contrato formal entre um serviço e um cliente que descreve abstratamente os dados a serem trocados.

O contrato de dados pode ser explícito ou implícito. Um tipo simples como int, string etc tem um contrato de dados implícito. O objeto definido pelo usuário é explícito ou do tipo Complex, para o qual é necessário definir um contrato de dados usando os atributos [DataContract] e [DataMember].

Um contrato de dados pode ser definido da seguinte maneira:

  • Descreve o formato externo dos dados transmitidos para e das operações de serviço

  • Ele define a estrutura e os tipos de dados trocados nas mensagens de serviço

  • Ele mapeia um tipo de CLR para um esquema XML
  • Ele define como os tipos de dados são serializados e desserializados. Por meio da serialização, você converte um objeto em uma sequência de bytes que pode ser transmitida por uma rede. Por meio da desserialização, você remonta um objeto a partir de uma sequência de bytes que recebe de um aplicativo de chamada.
  • É um sistema de controle de versão que permite gerenciar alterações nos dados estruturados

Precisamos incluir a referência System.Runtime.Serialization no projeto. Este assembly contém os atributos DataContract e DataMember.

Kamran
fonte
2
  1. Contrato de dados: especifica que sua classe de entidade está pronta para o processo de serialização.

  2. Membros dos dados: especifica que o campo específico faz parte do contrato de dados e pode ser serializado.

Mrunalini
fonte
0

Além disso, quando você chama da solicitação http, ela funciona corretamente, mas quando você tenta ligar da net.tcp, dessa vez, obtém todo esse tipo de coisa

Pramod
fonte
0

O atributo DataMember não é obrigatório para adicionar aos dados de serialização. Quando o atributo DataMember não é adicionado, o XMLSerializer antigo serializa os dados. A adição de um DataMember fornece propriedades úteis, como order, name, isrequired que não podem ser usadas de outra forma.

Vijay Mishra
fonte