WCF - Serializando objeto con otro objeto anidado

30/04/2009 - 10:40 por lobezno | Informe spam
hola a todos,
tengo problemas al serializar objetos "Padre-hijo" con WCF.

Os paso código que es más fácil verlo así, q explicarlo.

[DataContract]
public class Peticion
{
string _titulo;
IList<Requisito> _requisitos = new List<Requisito>;

[DataMember]
public string Titulo
{
get { return _titulo; }
set { _titulo = value; }
}

[DataMember]
public IList<Requisito> Requisitos
{
get { return _requisitos; }
set { _requisitos = value; }
}

public void AddRequisito(Requisito r, Peticion p)
{
r.Padre = p;
this.Requisitos.Add(r);
}
}

[DataContract]
public class Requisito
{
private string _nombre;
private Peticion _padre;

[DataMember]
public string Nombre
{
get { return _nombre; }
set { _nombre = value; }
}

[DataMember]
public Peticion Padre
{
get { return _padre; }
set { _padre = value; }
}
}

Con esta definición de clases, tengo un servicio que devuelve un objeto de
tipo Peticion (que internamente tiene una lista de requisitos). Con esto me
da un error al retornar el objeto:
"Error al recibir la respuesta HTTP a
http://localhost:8731/ServicioPeticion/. Puede deberse a que el enlace del
extremo de servicio no usa el protocolo HTTP. También puede deberse a que el
servidor anula un contexto de solicitud HTTP (posiblemente por el cierre del
servicio). Consulte los registros del servidor para obtener más información.
"

Por reducción al absurdo, veo que el problema está al decirle a un objeto
requisito, que su Padre, es el objeto Peticion. OJO, no falla al hacer:
r.Padre = p;, falla en el return del servicio, pero si quito esa linea, el
servicio funciona bien, de hecho, si quito el [DataMember] de Padre, tb
funciona bien, por lo que deduzco q falla la serializacion del objeto
Peticion.

Por algún motivo, parece que no sabe serializar el objeto Peticion, que
tiene un Requiisto que a su vez tiene el mismo objeto Peticion en su
propiedad padre :)

Alguna idea de cómo puedo solucionar esto???

Muchas gracias,
Un saludo!

Preguntas similare

Leer las respuestas

#1 Willy Mejia
30/04/2009 - 16:56 | Informe spam
Utiliza ServiceKnownType para especificar el tipo "Peticion" en tu
ServiceContract:
http://msdn.microsoft.com/library/s...ibute.aspx

Saludos,
Willy Mejía


"lobezno" escribió en el mensaje de
noticias:
hola a todos,
tengo problemas al serializar objetos "Padre-hijo" con WCF.

Os paso código que es más fácil verlo así, q explicarlo.

[DataContract]
public class Peticion
{
string _titulo;
IList<Requisito> _requisitos = new List<Requisito>;

[DataMember]
public string Titulo
{
get { return _titulo; }
set { _titulo = value; }
}

[DataMember]
public IList<Requisito> Requisitos
{
get { return _requisitos; }
set { _requisitos = value; }
}

public void AddRequisito(Requisito r, Peticion p)
{
r.Padre = p;
this.Requisitos.Add(r);
}
}

[DataContract]
public class Requisito
{
private string _nombre;
private Peticion _padre;

[DataMember]
public string Nombre
{
get { return _nombre; }
set { _nombre = value; }
}

[DataMember]
public Peticion Padre
{
get { return _padre; }
set { _padre = value; }
}
}

Con esta definición de clases, tengo un servicio que devuelve un objeto de
tipo Peticion (que internamente tiene una lista de requisitos). Con esto
me
da un error al retornar el objeto:
"Error al recibir la respuesta HTTP a
http://localhost:8731/ServicioPeticion/. Puede deberse a que el enlace del
extremo de servicio no usa el protocolo HTTP. También puede deberse a que
el
servidor anula un contexto de solicitud HTTP (posiblemente por el cierre
del
servicio). Consulte los registros del servidor para obtener más
información.
"

Por reducción al absurdo, veo que el problema está al decirle a un objeto
requisito, que su Padre, es el objeto Peticion. OJO, no falla al hacer:
r.Padre = p;, falla en el return del servicio, pero si quito esa linea, el
servicio funciona bien, de hecho, si quito el [DataMember] de Padre, tb
funciona bien, por lo que deduzco q falla la serializacion del objeto
Peticion.

Por algún motivo, parece que no sabe serializar el objeto Peticion, que
tiene un Requiisto que a su vez tiene el mismo objeto Peticion en su
propiedad padre :)

Alguna idea de cómo puedo solucionar esto???

Muchas gracias,
Un saludo!
Respuesta Responder a este mensaje
#2 lobezno
01/05/2009 - 20:42 | Informe spam
hola!

he leído el enlace y algunos más. seguro q tiene q salir con eso, pero he
probado a poner:
[ServiceKnownType(typeof(Peticion))]
[ServiceKnownType(typeof(Requisito))]
en la Interfaz del servicio (junto al ServiceContract), pero sigue igual.

Tb he probado a poner en la clase Requisito:
[KnownType(typeof(Peticion))]

Pero tampoco. En general, he probado con esos atributos en casi todas las
combinaciones posibles, pero no lo consigo :(

Alguna idea??

Gracias de nuevo.

"Willy Mejia" wrote:

Utiliza ServiceKnownType para especificar el tipo "Peticion" en tu
ServiceContract:
http://msdn.microsoft.com/library/s...ibute.aspx

Saludos,
Willy Mejía


"lobezno" escribió en el mensaje de
noticias:
> hola a todos,
> tengo problemas al serializar objetos "Padre-hijo" con WCF.
>
> Os paso código que es más fácil verlo así, q explicarlo.
>
> [DataContract]
> public class Peticion
> {
> string _titulo;
> IList<Requisito> _requisitos = new List<Requisito>;
>
> [DataMember]
> public string Titulo
> {
> get { return _titulo; }
> set { _titulo = value; }
> }
>
> [DataMember]
> public IList<Requisito> Requisitos
> {
> get { return _requisitos; }
> set { _requisitos = value; }
> }
>
> public void AddRequisito(Requisito r, Peticion p)
> {
> r.Padre = p;
> this.Requisitos.Add(r);
> }
> }
>
> [DataContract]
> public class Requisito
> {
> private string _nombre;
> private Peticion _padre;
>
> [DataMember]
> public string Nombre
> {
> get { return _nombre; }
> set { _nombre = value; }
> }
>
> [DataMember]
> public Peticion Padre
> {
> get { return _padre; }
> set { _padre = value; }
> }
> }
>
> Con esta definición de clases, tengo un servicio que devuelve un objeto de
> tipo Peticion (que internamente tiene una lista de requisitos). Con esto
> me
> da un error al retornar el objeto:
> "Error al recibir la respuesta HTTP a
> http://localhost:8731/ServicioPeticion/. Puede deberse a que el enlace del
> extremo de servicio no usa el protocolo HTTP. También puede deberse a que
> el
> servidor anula un contexto de solicitud HTTP (posiblemente por el cierre
> del
> servicio). Consulte los registros del servidor para obtener más
> información.
> "
>
> Por reducción al absurdo, veo que el problema está al decirle a un objeto
> requisito, que su Padre, es el objeto Peticion. OJO, no falla al hacer:
> r.Padre = p;, falla en el return del servicio, pero si quito esa linea, el
> servicio funciona bien, de hecho, si quito el [DataMember] de Padre, tb
> funciona bien, por lo que deduzco q falla la serializacion del objeto
> Peticion.
>
> Por algún motivo, parece que no sabe serializar el objeto Peticion, que
> tiene un Requiisto que a su vez tiene el mismo objeto Peticion en su
> propiedad padre :)
>
> Alguna idea de cómo puedo solucionar esto???
>
> Muchas gracias,
> Un saludo!

Respuesta Responder a este mensaje
#3 Willy Mejia
02/05/2009 - 00:05 | Informe spam
Mea culpa... Por similitud asocié tu caso a otro que se resolvía con ese
atributo. Pero leyendo bien me doy cuenta que el problema está en la
relación por referencia al objeto "padre".

Así que ahora la pregunta es: ¿Que tan necesario es incluir dicha relación
por referencia? ¿Puedes sustituirla por una por identificador? ¿Puedes
prescindir de ella? En caso negativo, entonces tendrás que hacerla en el
cliente. Esto debido a que una referencia a un objeto sólo tiene sentido y
es posible a nivel de la memoria de la máquina.

Así pues, transmite la petición (con sus requisitos) como datos de respuesta
de tu servicio y del lado del cliente crea y mapea los objetos de manera que
reflejen la relación por referencia. De hecho siempre se debería hacer un
mapeo entre los "datos" que se transmiten por servicios web y las
"entidades" propiamente dichas.

Saludos,
Willy Mejía.


"lobezno" escribió en el mensaje de
noticias:
hola!

he leído el enlace y algunos más. seguro q tiene q salir con eso, pero he
probado a poner:
[ServiceKnownType(typeof(Peticion))]
[ServiceKnownType(typeof(Requisito))]
en la Interfaz del servicio (junto al ServiceContract), pero sigue igual.

Tb he probado a poner en la clase Requisito:
[KnownType(typeof(Peticion))]

Pero tampoco. En general, he probado con esos atributos en casi todas las
combinaciones posibles, pero no lo consigo :(

Alguna idea??

Gracias de nuevo.

"Willy Mejia" wrote:

Utiliza ServiceKnownType para especificar el tipo "Peticion" en tu
ServiceContract:
http://msdn.microsoft.com/library/s...ibute.aspx

Saludos,
Willy Mejía


"lobezno" escribió en el mensaje de
noticias:
> hola a todos,
> tengo problemas al serializar objetos "Padre-hijo" con WCF.
>
> Os paso código que es más fácil verlo así, q explicarlo.
>
> [DataContract]
> public class Peticion
> {
> string _titulo;
> IList<Requisito> _requisitos = new List<Requisito>;
>
> [DataMember]
> public string Titulo
> {
> get { return _titulo; }
> set { _titulo = value; }
> }
>
> [DataMember]
> public IList<Requisito> Requisitos
> {
> get { return _requisitos; }
> set { _requisitos = value; }
> }
>
> public void AddRequisito(Requisito r, Peticion p)
> {
> r.Padre = p;
> this.Requisitos.Add(r);
> }
> }
>
> [DataContract]
> public class Requisito
> {
> private string _nombre;
> private Peticion _padre;
>
> [DataMember]
> public string Nombre
> {
> get { return _nombre; }
> set { _nombre = value; }
> }
>
> [DataMember]
> public Peticion Padre
> {
> get { return _padre; }
> set { _padre = value; }
> }
> }
>
> Con esta definición de clases, tengo un servicio que devuelve un objeto
> de
> tipo Peticion (que internamente tiene una lista de requisitos). Con
> esto
> me
> da un error al retornar el objeto:
> "Error al recibir la respuesta HTTP a
> http://localhost:8731/ServicioPeticion/. Puede deberse a que el enlace
> del
> extremo de servicio no usa el protocolo HTTP. También puede deberse a
> que
> el
> servidor anula un contexto de solicitud HTTP (posiblemente por el
> cierre
> del
> servicio). Consulte los registros del servidor para obtener más
> información.
> "
>
> Por reducción al absurdo, veo que el problema está al decirle a un
> objeto
> requisito, que su Padre, es el objeto Peticion. OJO, no falla al hacer:
> r.Padre = p;, falla en el return del servicio, pero si quito esa linea,
> el
> servicio funciona bien, de hecho, si quito el [DataMember] de Padre, tb
> funciona bien, por lo que deduzco q falla la serializacion del objeto
> Peticion.
>
> Por algún motivo, parece que no sabe serializar el objeto Peticion, que
> tiene un Requiisto que a su vez tiene el mismo objeto Peticion en su
> propiedad padre :)
>
> Alguna idea de cómo puedo solucionar esto???
>
> Muchas gracias,
> Un saludo!

Respuesta Responder a este mensaje
#4 lobezno
04/05/2009 - 09:22 | Informe spam
Hola de nuevo!! No problem.

La relación (algo tonta, la verdad), la necesito porque estoy usando
nHibernate para persistir en BD y si no hago esa relación, no he conseguido
hacerlo funcionar (x raro q me parezca).

Ahora mismo lo estoy solucionando como dices, no necesito que esa relación
viaje hacia el cliente (ni viceversa), lo q hago es ponerla antes de usar
nHibernate, y todo OK. De todas formas, me gustaría entender por qué no puedo
hacer algo así cn WCF, ya que no me parece muy diferente a la lista de
Requisitos del objeto Peticion (al final es un objeto que contiene
propiedades de otros objetos definidos por mi). Supongo que será por lo q
comentas de la memoria, pero no lo termino de entender.

Si me lo puedes aclarar algo más, perfecto, si no, pues lo dejamos así, q
funciona :)

Gracias!!!!

"Willy Mejia" wrote:

Mea culpa... Por similitud asocié tu caso a otro que se resolvía con ese
atributo. Pero leyendo bien me doy cuenta que el problema está en la
relación por referencia al objeto "padre".

Así que ahora la pregunta es: ¿Que tan necesario es incluir dicha relación
por referencia? ¿Puedes sustituirla por una por identificador? ¿Puedes
prescindir de ella? En caso negativo, entonces tendrás que hacerla en el
cliente. Esto debido a que una referencia a un objeto sólo tiene sentido y
es posible a nivel de la memoria de la máquina.

Así pues, transmite la petición (con sus requisitos) como datos de respuesta
de tu servicio y del lado del cliente crea y mapea los objetos de manera que
reflejen la relación por referencia. De hecho siempre se debería hacer un
mapeo entre los "datos" que se transmiten por servicios web y las
"entidades" propiamente dichas.

Saludos,
Willy Mejía.


"lobezno" escribió en el mensaje de
noticias:
> hola!
>
> he leído el enlace y algunos más. seguro q tiene q salir con eso, pero he
> probado a poner:
> [ServiceKnownType(typeof(Peticion))]
> [ServiceKnownType(typeof(Requisito))]
> en la Interfaz del servicio (junto al ServiceContract), pero sigue igual.
>
> Tb he probado a poner en la clase Requisito:
> [KnownType(typeof(Peticion))]
>
> Pero tampoco. En general, he probado con esos atributos en casi todas las
> combinaciones posibles, pero no lo consigo :(
>
> Alguna idea??
>
> Gracias de nuevo.
>
> "Willy Mejia" wrote:
>
>> Utiliza ServiceKnownType para especificar el tipo "Peticion" en tu
>> ServiceContract:
>> http://msdn.microsoft.com/library/s...ibute.aspx
>>
>> Saludos,
>> Willy Mejía
>>
>>
>> "lobezno" escribió en el mensaje de
>> noticias:
>> > hola a todos,
>> > tengo problemas al serializar objetos "Padre-hijo" con WCF.
>> >
>> > Os paso código que es más fácil verlo así, q explicarlo.
>> >
>> > [DataContract]
>> > public class Peticion
>> > {
>> > string _titulo;
>> > IList<Requisito> _requisitos = new List<Requisito>;
>> >
>> > [DataMember]
>> > public string Titulo
>> > {
>> > get { return _titulo; }
>> > set { _titulo = value; }
>> > }
>> >
>> > [DataMember]
>> > public IList<Requisito> Requisitos
>> > {
>> > get { return _requisitos; }
>> > set { _requisitos = value; }
>> > }
>> >
>> > public void AddRequisito(Requisito r, Peticion p)
>> > {
>> > r.Padre = p;
>> > this.Requisitos.Add(r);
>> > }
>> > }
>> >
>> > [DataContract]
>> > public class Requisito
>> > {
>> > private string _nombre;
>> > private Peticion _padre;
>> >
>> > [DataMember]
>> > public string Nombre
>> > {
>> > get { return _nombre; }
>> > set { _nombre = value; }
>> > }
>> >
>> > [DataMember]
>> > public Peticion Padre
>> > {
>> > get { return _padre; }
>> > set { _padre = value; }
>> > }
>> > }
>> >
>> > Con esta definición de clases, tengo un servicio que devuelve un objeto
>> > de
>> > tipo Peticion (que internamente tiene una lista de requisitos). Con
>> > esto
>> > me
>> > da un error al retornar el objeto:
>> > "Error al recibir la respuesta HTTP a
>> > http://localhost:8731/ServicioPeticion/. Puede deberse a que el enlace
>> > del
>> > extremo de servicio no usa el protocolo HTTP. También puede deberse a
>> > que
>> > el
>> > servidor anula un contexto de solicitud HTTP (posiblemente por el
>> > cierre
>> > del
>> > servicio). Consulte los registros del servidor para obtener más
>> > información.
>> > "
>> >
>> > Por reducción al absurdo, veo que el problema está al decirle a un
>> > objeto
>> > requisito, que su Padre, es el objeto Peticion. OJO, no falla al hacer:
>> > r.Padre = p;, falla en el return del servicio, pero si quito esa linea,
>> > el
>> > servicio funciona bien, de hecho, si quito el [DataMember] de Padre, tb
>> > funciona bien, por lo que deduzco q falla la serializacion del objeto
>> > Peticion.
>> >
>> > Por algún motivo, parece que no sabe serializar el objeto Peticion, que
>> > tiene un Requiisto que a su vez tiene el mismo objeto Peticion en su
>> > propiedad padre :)
>> >
>> > Alguna idea de cómo puedo solucionar esto???
>> >
>> > Muchas gracias,
>> > Un saludo!
>>
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida