visual studio serialize data wcf

studio - ¿Cuál es el objetivo de un DataContract en WCF?



reference datacontract (6)

VS.net crea una plantilla cuando crea un proyecto WCF.

Agrega una clase al archivo iService1.cs:

// Use a data contract as illustrated in the sample below to // add composite types to service operations. [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } }

Como un servicio WCF puede devolver cualquier clase definida por el usuario, ¿por qué usar una clase DataContract y CompositeType?

Puedo devolver algo como:

[OperationContract] MyUserCollection GetUsers();

¿Qué me estoy perdiendo?


DataContract es solo una definición formal de un tipo que se puede entender en ambos lados del límite del servicio.

Si devuelve, como en su ejemplo, un objeto "MyUserCollection", los consumidores de su servicio necesitarán hacer referencia a las entrañas de su servicio / sistema, que es una violación del principio SOA de los límites explícitos. Al usar un DataContract, usted está publicando la estructura de sus tipos de devolución de una manera flexible.


Hay otro uso importante: puede cambiar el Nombre de la clase y las propiedades. Es una característica útil durante la serialización y la deserialización.

[DataContract(Name="EmployeeName")] public class Person { [DataMember(Name="FullName")] public string Name { get; set; } [DataMember(Name="HomeAddress")] public string Address { get; set; } }


No estoy de acuerdo con el afiche que dijo "The DataContract es solo una definición formal de un tipo que se puede entender en ambos lados del límite del servicio".

La palabra clave aquí es "tipo". En .NET, un tipo es un objeto que puede tener campos, propiedades y métodos. Sin embargo, cuando decora una clase con DataContract en su servicio WCF, el resultado no es la clase que se trasplanta mágicamente en el código de llamada; ¡ni por asomo! En el código de llamada, tendrá una clase "proxy". La clase proxy recibe XML que representa el contenido del contrato de datos. El código de llamada puede recibir estos valores XML a través de la clase proxy, pero no da acceso al código de llamada a las entrañas de la clase decorar con datacontract .


Otra cosa interesante de notar es que si decora su código con DataContract, tiene mucho control sobre lo que el cliente puede ver y debe devolverlo a su servicio. Por ejemplo:

[DataContract] public class SampleClass { [DataMember(IsRequired=true)] public int MyRequiredProperty { get; set; } [DataMember] public int MyOptionalProperty { get; set; } public int MyInternalProperty { get; set; } }

En el ejemplo anterior, usted definió que al recibir datos, DEBE tener MyRequiredProperty, y puede tener o no MyOptionalProperty. Además, el cliente nunca verá MyInternalProperty (esto puede ser, por ejemplo, una propiedad que ayuda con su lógica internamente, pero no desea que se exponga a nivel del cliente).


Para responder a "marc_s":

"Si tiene .NET en ambos extremos del cable, está bien. ¿Qué sucede si tiene un cliente Java que llama a su servicio? Si coloca sus datos dentro de DataContracts, esa información se almacena en los metadatos WSDL / XSD y se puede usar por clientes que no sean .NET, también ".

Creo que es falso Tratemos de hacer esto:

  1. Use el ejemplo predeterminado del proyecto WCF con una clase con atributos DataContract en clases y DataMember en miembros, y un método que devuelva este tipo.
  2. Compilarlo y mostrar el wsdl. El xsd contiene la definición de CompositeType. DE ACUERDO.
  3. Ahora borremos todos los atributos DataContract y DataMember
  4. Compilarlo y mostrar el wsdl. ¡El xsd todavía contiene la definición de ComposityType! (es más obvio con un software SCM suave, que no muestra diferencias en los archivos entre los pasos 2 y 4)

¡Así que un cliente Java debería gestionar esto, sin DataContract y DataMember! ¿Estoy equivocado o qué?


Tal vez no se use a menudo, podríamos usar [DataContract] para pasar a través de variables privadas. DataContractSerializer serializará / deserializará solo los tipos visibles públicamente si el atributo [DataContract] no se utiliza.

[DataContract] public class SampleClass { [DataMember] private int MyPrivateProperty { get; set; } }

(Nota: si está generando un proxy, los miembros privados se exponen como públicos)