Estoy compilando una aplicación usando MVC3, motor Razor view, Repository Pattern with Unit of Work y usando EF4.1 Code First para definir mi modelo de datos.Serialización de entidades EF4.1 usando JSON.Net
Aquí hay un poco de fondo (si no lo quiere, gírelo).
La aplicación en sí es solo un 'Menú' de la Intranet.
Los 2 entidades principales son Menultem y el Departamento de los cuales:
- Menultem puede tener muchos departamentos
- Departamentos pueden tener muchos MenuItems
- Menultem puede tener un Menultem como padre
Así es como he definido mis Entidades
public class MenuItem
{
public int MenuItemId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public virtual ICollection<Department> Departments { get; set; }
public int? ParentId { get; set; }
public virtual MenuItem ParentMenuItem { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
public string Name { get; set; }
public virtual ICollection<MenuItem> MenuItems { get; set; }
}
Uso FluentAPI para definir la referencia automática Muchos a muchos para MenuItem.
El problema que tengo es pasar un elemento de menú a la vista a través de JSON. Los problemas centrales son que tengo una referencia circular entre mis entidades que el analizador JSON integrado no puede tratar y tengo la carga diferida y la generación de proxy todavía habilitada.
Estoy usando la biblioteca JSON.net de Nuget como mi serializador JSON, ya que parece ser una buena manera de resolver el problema de referencia circular. Ahora no estoy seguro de cómo 'arreglar' el problema de generación de proxy. Actualmente el serializador arroja The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships.
¿Alguien puede ayudarme con esto? Si desactivo la generación de proxy, voy a tener muchísimo tiempo cargando todos los elementos de MenuItem, así que estoy interesado en dejar esto. He leído una buena cantidad y parece que hay una variedad de respuestas diferentes, incluyendo la proyección de las entidades en otro objeto y serializar eso, etc. Idealmente, ¿habría alguna forma de configurar JSON.net para ignorar el objeto RelationshipManager?
actualización
Aquí es lo que he usado como un serializador personalizado ContractResolver para JSON.Net. Esto parece haber solucionado mi problema.
public class ContractResolver : DefaultContractResolver
{
private static readonly IEnumerable<Type> Types = GetEntityTypes();
private static IEnumerable<Type> GetEntityTypes()
{
var assembly = Assembly.GetAssembly(typeof (IEntity));
var types = assembly.GetTypes().Where(t => String.Equals(t.Namespace, "Namespace", StringComparison.Ordinal));
return types;
}
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
if (!AllowType(objectType))
return new List<MemberInfo>();
var members = base.GetSerializableMembers(objectType);
members.RemoveAll(memberInfo => (IsMemberEntityWrapper(memberInfo)));
return members;
}
private static bool AllowType(Type objectType)
{
return Types.Contains(objectType) || Types.Contains(objectType.BaseType);
}
private static bool IsMemberEntityWrapper(MemberInfo memberInfo)
{
return memberInfo.Name == "_entityWrapper";
}
}
IEntity
es una interfaz todo mi Código primera entidad de objetos implementar.
Gracias Ladislav. De su publicación de blog referenciada, pude escribir un 'ContractResolver' personalizado para especificar qué miembros, y más específicamente qué tipos de objetos, resulta ser serializar. En algunos casos, se estaba transfiriendo un objeto de framework para ser serializado, así que tuve que verificar el tipo de objeto. Actualizaré mi pregunta con el código que he usado. Siéntase libre de comentar al respecto :) –