serialize serializar serializacion deserializar deserializacion .net wcf serialization

.net - serializar - Atributo WCF: DataMember en propiedad vs. miembro



serialize wikipedia (7)

En wcf, ¿cuál es la diferencia entre aplicar el atributo DataMember en una propiedad

private int m_SomeValue; [DataMember] public int SomeValue { get {...} set {...} }

en lugar de una variable miembro

[DataMember] private int m_SomeValue; public int SomeValue { get {...} set {...} }

?


En general, debe favorecer la aplicación del atributo DataMember en la propiedad, en lugar de hacerlo en el campo privado. La única razón para aplicar el atributo al campo es si la propiedad era de solo lectura (es decir, no tiene un setter).


En teoría, y siempre que mantenga m_SomeValue siempre igual a SomeValue (como un simple getter / setter), nada. Aparte del nombre de la variable expuesta por el WCF. (Obviamente, si etiqueta la variable m_ , su clase proxy también tendrá el mismo nombre m_ . La clase proxy generará una propiedad pública independientemente de que use un campo o propiedad público / protegido / interno / privado.

Sin embargo, si tiene alguna lógica especial en sus ToUpper() que pueda modificar el valor devuelto ( ToUpper() ing string, por ejemplo), devolverá un valor diferente.


Esta decisión depende del uso de su servicio WCF:

  1. Servicio interno consumido por sus propios sistemas .NET, que comparten el mismo modelo de dominio.
  2. Servicio externo consumido por diferentes plataformas, que no comparten el mismo Modelo de Dominio.

Caso 1.

Serialización: es el proceso de persistencia del estado del objeto. El estado del objeto en C # está representado por sus campos de datos.

Las propiedades en C # son esencialmente métodos que manipulan el estado del objeto. Su uso puede dar como resultado una deserialización diferente del estado del objeto, ya que el orden en que se establecen las propiedades puede tener un impacto en su estado de datos final. Otros factores pueden dar como resultado una deserialización de estado incorrecta también, si, por ejemplo, el método (conjunto de propiedades) se basa en algún contexto que está cambiando, como DateTime actual.

Usted puede decir ¿qué pasa con la encapsulación? No quiero que mi objeto esté en estado inválido, y debo hacer comprobaciones de validación, verificaciones de integridad del gráfico de objetos, etc. Sí, deberías, ¿entonces ponemos los atributos de DataMember en puntales? No.

El problema aquí es que muchas personas mezclan dos cosas diferentes, DTO (Data Transfer Object, WCF Contract) con Domain Entity. Lo que necesita es asegurarse de que los datos que recibe sean, en esencia, los mismos que se enviaron, y luego asegurarse de que puede construir una Entidad de dominio válida a partir de estos datos. La mejor manera de lograr esto es usar clases separadas para DTO, y construir una Entidad de dominio a partir de ellas.

Pero la mayoría de los programadores son flojos, y les gusta decorar de forma simple la entidad de dominio con los atributos de DataMemeber. En este caso, la decisión Campo o Prop depende de dónde está su lógica de validación; si su lógica de validación está oculta en los métodos Establecer, deberá usar los Apoyos, si es externo, debe usar Campos y validar su Entidad de dominio después de la desirialización.

PD. Creo que las mismas reglas se aplican a cualquier proceso de serialización, como la persistencia de la base de datos.

Además, me gustaría mencionar que Silverlight no puede serializar / deserializar campos privados, porque no puede acceder a ellos desde fuera mediante el uso de la reflexión, y deberá hacerlos privados y usar InternalsVisibleToAttribute.

Caso 2

Esto es difícil. El enfoque principal aquí es la interoperabilidad. En el 99.9% tendrá clases separadas de DTO en este caso y lo más probable es que haya una gran cantidad de diferentes versiones para admitir clientes antiguos. No importa dónde coloque DataMembers attribs en esto, porque usa DTO''s. No me molestaré en explicar este escenario, porque los desarrolladores que trabajan en un sistema de gran escala suelen tener bastante experiencia y no se molestan en leer SO.


Hay buenas razones por las que puede querer marcar campos en lugar de propiedades como DataMember.

Por favor, consulte esto para más detalles: http://blog.walteralmeida.com/2010/05/wcf-and-datacontract-serialization-internals-and-tips-.html

Por cierto: ContractSerializers serializará cualquier campo privado que tenga el DataMemberAttribute solo si se ejecuta en un entorno de confianza total . No funciona en confianza parcial (consulte el blog mencionado anteriormente para obtener una solución)


Personalmente, usaría la propiedad y eliminaría por completo la variable miembro todos juntos. es decir

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

La propiedad inexplicablemente creará una variable miembro detrás de escena.


Si agrega [DataMember] en private int m_SomeValue, este miembro no puede ser serializado, por lo tanto debe agregarlo en public int SomeValue.

[DataMember]
private int m_SomeValue;

public int SomeValue {get {...} set {...}}

el código de arriba no puede obtener valor en el cliente si lo usa a través de WCF.


Siempre que use el marcador Name , el contrato es idéntico independientemente de si se usa el campo o la propiedad.

[DataMember(Name="SomeValue")] private int m_SomeValue;

Sin embargo, puede haber algunos problemas de permisos para acceder a miembros privados, en particular en silverlight y CF, en cuyo caso recomendaría usar la propiedad pública como miembro de datos. En realidad, tendería a usar siempre una propiedad a menos que tuviera una muy buena razón ...