visual test studio open how wcf anonymous-types datacontractserializer datacontract

test - Pasar una instancia de tipo anónimo sobre WCF



wcf test visual studio 2017 (6)

Como se dijo antes, los objetos deben ser deserializables, por lo que deberá definir la estructura de antemano. Sin embargo, puede usar la herencia para definirlos y, por lo tanto, disminuir el dolor. WCF proporciona el atributo KnownType para permitir que una Operación de Servicio reciba un objeto de la clase base y lo deserialice en un objeto de una clase derivada. Por lo tanto, solo tendrá una (o algunas) operaciones de servicio que puedan manejar todos sus escenarios.

Tengo un método de servicio WCF que espera un objeto y luego recupera sus propiedades mediante la reflexión.

En el lado del cliente, creo un objeto de tipo anónimo

var obj = new {FirstName="John", LastName="Doe"}

y pasarlo al método. Estoy recibiendo una excepción:

Type ''<>f__AnonymousType0`2[System.String,System.String]'' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

No puedo marcar el tipo o sus miembros con atributos de serialización porque realmente no hay ningún tipo ni propiedades declaradas explícitamente. ¿Hay alguna forma de superar ese problema?


Las respuestas que sugieren que no puede usar un tipo anónimo sobre WCF son incorrectas.

Si está utilizando el DataContractSerializer predeterminado para serializar sus tipos en el canal, entonces sí, las respuestas son correctas. Esto se debe a que DataContractSerializer admite los siguientes escenarios:

  1. Tipos serializados utilizando el atributo Serializable
  2. Tipos serializados mediante serialización XML
  3. Tipos serializados utilizando el atributo DataContract
  4. Plain-Old-C # -Object (POCO) Serialization

Respectivamente, fallan con tipos anónimos debido a lo siguiente:

  1. No puede aplicar atributos a tipos anónimos.
  2. La serialización XML requiere un constructor sin parámetros predeterminado, que los tipos anónimos no tienen.
  3. Igual que 1.
  4. Igual que 2.

Sin embargo , no está obligado a utilizar DataContractSerializer para serializar sus mensajes en WCF. Puede crear un formateador de mensajes personalizado que puede usar para realizar la serialización usted mismo.

Tiene un problema si los tipos que está enviando como resultado de las solicitudes son de tipo anónimo. Cuando obtenga los resultados, tendrá un nombre definido dentro de un espacio de nombres (no en un sentido .NET, pero en un sentido SOA) y tendrá que manejar el mapeo de ese tipo concreto de nuevo al tipo anónimo . Sin embargo, como no tiene acceso al tipo anónimo real ni a las formas de construirlo en código (al menos de forma dinámica), no tiene más remedio que pasarlo como un objeto si se le transfiere a usted, lo cual lo hace un poco inútil, ya que todos tendrán que usar malas prácticas, como la dinámica (no es una mala práctica en sí misma, sino superar estas limitaciones en este caso, sí), o cast-by-example .

Así que, al final, diré que, si bien es posible serializar tipos anónimos y enviarlos por cable, el trabajo invocado generalmente no vale la pena.


No hagas esto

Es un intento de ser inteligente. No lo hagas Simplemente declare el tipo de datos que necesita y úselo. Si necesita un tipo de datos definido de manera más vaga, solo use un mapa de clave-valor de algún tipo.

Te tomará 5 minutos escribir algo que pueda manejar esto para siempre. Usar cualquier técnica como esta le costará horas de depuración en algún punto futuro en el futuro.


No no hay. Si bien hay trucos y técnicas para devolver objetos de un tipo anónimo a partir de un método, no puede enviarlos a través de WCF.

WCF necesita conocer todos sus tipos concretos que se enviarán, ya que en realidad no se está llamando a un método .NET. En cambio, la llamada de mensaje se convierte en un mensaje serializado y, por lo tanto, cualquier "cosa" que se pase por una llamada WCF debe ser serializable, sin excepciones.


Puede serializar el objeto en una cadena JSON y enviarlo a través de WCF, así:

//in WCF Server dynamic mysentclass = new { FirstName = "John", LastName = "Doe" }; string jsonstring = JsonConvert.SerializeObject(mysentclass, Newtonsoft.Json.Formatting.Indented); //send the string through WCF //in WCF client dynamic myreceivedclass = JsonConvert.DeserializeObject<dynamic>(jsonstring); MessageBox.Show(myreceivedclass.FirstName.ToString() + " " + myreceivedclass.LastName.ToString());

El ejemplo usa Json.Net, que se puede obtener aquí:

http://www.nuget.org/packages/Newtonsoft.Json/

También podría usar System.Web.Script.Serialization.JavaScriptSerializer (en System.Web.Extensions.dll), que no es tan poderoso como Json.Net, pero sería suficiente para objetos simples.


Ya tienes la respuesta. No se puede hacer.

De hecho, no puede pasar una instancia de un tipo anónimo de un método a otro dentro de su programa. Ciertamente no puedes pasarlos entre programas.