Я создаю приложение, используя MVC3, Razor View Engine, Шаблон репозитория с единицей работы и использую код EF4.1 First для определения моей модели данных.
Вот немного фона (если хотите, закрасьте его).
Само приложение представляет собой «Меню» Интранета.
2 основных объекта - это MenuItem и Департамент, из которых:
- MenuItem может иметь много отделов
- У отделов может быть много MenuItems
- MenuItem может иметь MenuItem в качестве родителя
Так я определил свои сущности
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; }
}
Я использую FluentAPI для определения собственной ссылки «многие ко многим» для MenuItem.
У меня проблема с передачей MenuItem в представление через JSON.
Основные проблемы заключаются в том, что у меня есть круговая ссылка между объектами, с которой встроенный анализатор JSON не может справиться, и у меня все еще включена отложенная загрузка и генерация прокси.
Я использую библиотеку JSON.net от Nuget в качестве моего сериализатора JSON, так как это кажется хорошим способом решения проблемы циклических ссылок. Теперь я не уверен, как «исправить» проблему генерации прокси. В настоящее время сериализатор выбрасывает 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.
Может кто-нибудь помочь мне с этим? Если я отключу генерацию прокси, у меня будет адская загрузка всех детей MenuItem, поэтому я хочу оставить это включенным. Я прочитал достаточно много, и, кажется, существует множество разных ответов, включая проецирование сущностей в другой объект и сериализацию этого и т. Д., И т. Д. В идеале был бы какой-то способ настройки JSON.net для игнорирования объекта RelationshipManager?
Обновление
Вот что я использовал как пользовательский ContractResolver для сериализатора JSON.Net. Кажется, это решило мою проблему.
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
- это интерфейс, реализуемый всеми объектами сущности Code First.