5

Estoy tratando de generar una lista de objetos a un formato json utilizando la clase DataContractJsonSerializer, pero sigo corriendo el siguiente error.Problema DataContractResolver/KnownType cuando la clase personalizada contiene otra clase personalizada

Type 'Castle.Proxies.JokeCategoryProxy' with data contract name 
'JokeCategoryProxy:http://schemas.datacontract.org/2004/07/Castle.Proxies' 
is not expected. Consider using a DataContractResolver or add any types not 
known statically to the list of known types - for example, by using the 
KnownTypeAttribute attribute or by adding them to the list of known 
types passed to DataContractSerializer. 

Sé que esto ha sido respondida antes, pero sólo parece ocurrir cuando un objeto en mi tener una propiedad que es otro objeto personalizado.

[DataContract] 
[KnownType(typeof(ModelBase<int>))] 
public class Joke : ModelBase<int> 
{ 
    [DataMember] 
    public virtual string JokeText { get; set; } 

    [DataMember] 
    public virtual JokeCategory JokeCategory { get; set; } 
} 

[DataContract] 
[KnownType(typeof(ModelBase<int>))] 
public class JokeCategory : ModelBase<int> 
{ 
    [DataMember] 
    public virtual string Name { get; set; } 
} 

Como se puede ver el modelo Broma contiene un objeto Broma Categoría, si quito la Categoría Broma y simplemente tienen un int (JokeCategoryId) desaparece el error, aunque una solución, no un ideal como me gustaría tener la Categoría disponible sin tener que consultar de nuevo.

A continuación se muestra el código que estoy usando para generar el JSON

public static ContentResult JsonResponse<TReturnType>(this Controller controller, TReturnType data) 
    { 
     using (var oStream = new System.IO.MemoryStream()) 
     { 
      new DataContractJsonSerializer(typeof(TReturnType)).WriteObject(oStream, data); 

      return new ContentResult 
      { 
       ContentType = "application/json", 
       Content = Encoding.UTF8.GetString(oStream.ToArray()), 
       ContentEncoding = Encoding.UTF8 
      }; 
     } 
    } 

Lo que me confunde es el más referencias que el error Castle.Proxies.JokeCategoryProxy (donde ha salido esto ?!)

¿Alguna sugerencia?

Respuesta

5

nHibernate asume que todas sus propiedades, a menos que se especifique lo contrario, son de carga lenta.
Lo que eso significa es que, en su caso, el JokeCategory no se extrae de la BD cada vez que tira de su objeto Joke; en cambio, un 'proxy' se genera dinámicamente.
La primera vez que accede a esa propiedad nHibernate sabe cómo sacarla de la base de datos. (Esto es cómo funciona el perezoso de carga de NHib)

Así que básicamente lo que está pasando aquí es que usted espera que su JokeCategory a ser de tipo JokeCategory, pero ya que no es realmente initialized- es de tipo Proxy....

(esto es sólo una breve explicación; google algunos más en NHib y cómo funciona para averiguar más también se puede comprobar a cabo summer of nhibernate para una gran introducción a esta ORM.)

Y, a su pregunta: usted tiene un par de opciones aquí:

  1. de configuración que Categoría de propiedad como no perezoso, lo que obligará a NHibernate para inicializar con el tipo de objeto adecuado

  2. (mucho más preferible, en mi opinión) hacer n no serializar sus entidades modelo; en su lugar, construye algún tipo de DTO que contenga la información que tu capa de presentación necesite.
    De esta forma, su presentación no se verá afectada por los cambios en el modelo de dominio y viceversa.
    también, puede contener toda la información necesaria en su DTO, incluso si está relacionada con más de una entidad de modelo.

Por ejemplo:

public class JokeDTO 
    { 
     public int JokeId; 
     /*more Joke properties*/ 
     public int JokeCategoryId; 
     public string JokeCategoryName; 
     /*etc, etc..*/ 
    } 
+0

Muy útil sJhonny cosas. Por el momento no entraré en DTOs, pero los tendré en cuenta para futuros desarrollos. Utilizar .Not.LazyLoad() en mi archivo de mapeo nhibernate fluido funcionó perfectamente para resolver el problema inmediato. Muchas gracias. – JConstantine

Cuestiones relacionadas