2011-11-02 23 views
11

Tengo una entidad marco de entidad que deseo serializar como un objeto json. Miré a mi alrededor y descubrí que json.net (http://james.newtonking.com/projects/json-net.aspx) debería ser capaz de serializar objetos con referencias circulares "de fábrica". Así que traté de usarjson.net; serializar el objeto del marco de la entidad (error de referencia circular)

string json = JsonConvert.SerializeObject(/* my ef entity */); 

Pero sigo recibiendo el mismo error. El problema podría ser que necesito usar ReferenceLoopHandling.Ignore y ContractResolver, pero no estoy seguro de cómo usarlos. ¡Cualquier ayuda es muy apreciada! Gracias

+0

posible duplicado de [objetos Serialize Marco de la entidad en JSON] (http://stackoverflow.com/questions/657939/serialize-entity-framework-objects-into- json) –

+2

@CraigStuntz no, porque no quiero mapear las propiedades en un nuevo objeto. Y estoy preguntando cómo se puede hacer esto usando JSON.NET – Johan

+0

La solución propuesta funcionará para JSON.NET.Si realmente prefieres tratar con referencias circulares que con una declaración de asignación, bueno, eso depende de ti. Pero JSON.NET no significa que la otra solución no funcionará. –

Respuesta

2

Mi solución fue simplemente eliminar la referencia principal en las entidades de mi hijo.

Así que en mi modelo, seleccioné la relación y cambié la referencia principal para que fuera interna en lugar de pública.

Puede que no sea una solución ideal para todos, pero funcionó para mí.

14

Para evitar esto, convertí mis entidades a Code First basado en POCO. Para hacer esto, haga clic derecho dentro de su ventana de edmx y seleccione:

Agregue el elemento de generación de código> pestaña Código> EF POCO Entity Generator.

Tenga en cuenta que puede necesitar instalarlo con nuget si no lo ve.

En tiempo de ejecución, sin embargo, EF agrega clases de proxy a esos objetos con fines de seguimiento, pero tienden a hacer un lío con el proceso de serialización. Para evitar esto, simplemente puede establecer ProxyCreationEnabled en false de la siguiente manera:

var context = new YourEntities(); 
context.Configuration.ProxyCreationEnabled = false; 

var results = context.YourEntity.Take(100).ToList(); 

A continuación, puede volver con seguridad Json.NET datos serializados omitiendo la referencia por defecto bucle de la siguiente manera:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new JsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }); 
+4

+1 para 'ReferenceLoopHandling.Ignore' - ¡salvó mi día! – nrodic

1

Prueba esto: Primero asegurándose de que poco o modelo tiene DataContract, DataMemeber y quitar word..then tecla virtual ..

public string Get() 
    { 
     var list = _languageRepository.GetMany(l => l.LanguageTrans.FirstOrDefault().CultureCode == "en").ToList(); 

     string json = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); 

     return json; 
    } 
+0

De esta manera puede mantener entidades relacionadas ... – Bryant

9

Otra solución será la adición de [JsonIgnore] attribut e a sus propiedades de navegación.

Por ejemplo:

using System; 
using System.ComponentModel.DataAnnotations.Schema; 

[Serializable] 
public class Entity 
{ 
    public int EntityID { get; set; } 
    public string EntityName { get; set; } 

    [JsonIgnore] 
    public virtual Parent Parent { get; set; } 
    [JsonIgnore] 
    public virtual List<Child> Children { get; set; } 
} 
+0

Esta es la respuesta correcta, las entidades deben hacer referencia entre sí. Pero debe ignorar la propiedad de la entidad maestra en el niño. – Darren

+1

Pero, ¿qué ocurre si quiero ver la relación desde el punto de vista de elementos secundarios? –

6

que utiliza la siguiente solución para clonar mis entidades, sin trucos, donde los atributos necesarios en relación con los datos sobre las entidades y mis referencias circulares de mesa consiguieron conservan. Incluso tuve entidades señalando el uno al otro sin ningún problema. La biblioteca requerida para la serialización es Json.Net (Newtonsoft.Json dll). uso

private static T CloneObject<T>(T obj) 
    { 
     if (obj == null) 
      return obj; 
     string ser = JsonConvert.SerializeObject(obj, Formatting.Indented, 
      new JsonSerializerSettings() { 
           NullValueHandling = NullValueHandling.Ignore, 
           MissingMemberHandling = MissingMemberHandling.Ignore, 
           ReferenceLoopHandling = ReferenceLoopHandling.Ignore}); 
     return (T) JsonConvert.DeserializeObject(ser, obj.GetType()); 
    } 

Ejemplo:

protected object CopyObj(Object obj) 
    { 
     return CloneObject(obj); 
    } 
    var cust1 = this.cts.Customers().Where(cc => cc.Id == 3).Include(cc => cc.Addresses).FirstOrDefault(); 
    var cust2 = CopyObj(cust1) as Customers; 
    //Cust2 now includes copies of the customer record and its addresses 
Cuestiones relacionadas