Ошибка API-интерфейса Asp.Net: тип "ObjectContent`1" не смог сериализовать тело ответа для типа контента "application/xml"; кодировка = UTF-8'
Простейший пример этого, я получаю коллекцию и пытаюсь вывести ее через Web API:
// GET api/items
public IEnumerable<Item> Get()
{
return MyContext.Items.ToList();
}
И я получаю сообщение об ошибке:
Объект типа
'System.Data.Objects.ObjectQuery`1 [Dcip.Ams.BO.EquipmentWarranty] не могут быть преобразованы в тип
'System.Data.Entity.DbSet`1 [Dcip.Ams.BO.EquipmentWarranty]
Это довольно распространенная ошибка, связанная с новыми прокси-серверами, и я знаю, что могу исправить ее, установив:
MyContext.Configuration.ProxyCreationEnabled = false;
Но это поражает цель многих моих попыток. Есть ли лучший способ?
Ответы
Ответ 1
Я предлагаю отключить создание прокси только в том месте, где вам не нужно, или вызывает у вас проблемы. Вам не нужно отключать его во всем мире, вы можете просто отключить текущий контекст БД с помощью кода...
[HttpGet]
[WithDbContextApi]
public HttpResponseMessage Get(int take = 10, int skip = 0)
{
CurrentDbContext.Configuration.ProxyCreationEnabled = false;
var lista = CurrentDbContext.PaymentTypes
.OrderByDescending(x => x.Id)
.Skip(skip)
.Take(take)
.ToList();
var count = CurrentDbContext.PaymentTypes.Count();
return Request.CreateResponse(HttpStatusCode.OK, new { PaymentTypes = lista, TotalCount = count });
}
Здесь я только отключил ProxyCreation в этом методе, потому что для каждого запроса создается новый DBC-контекст, и поэтому я отключил ProxyCreation для этого случая.
Надеюсь, что это поможет.
Ответ 2
если у вас есть свойства навигации, и вы не хотите сделать их не виртуальными, вам следует использовать JSON.NET и изменить конфигурацию в App_Start на использование JSON not XML!
после установки JSON.NET From NuGet, вставьте этот код в WebApiConfig.cs в метод Register
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
Ответ 3
Если у вас есть свойства навигации, сделайте их не виртуальными. Картирование по-прежнему будет работать, но это предотвратит создание объектов динамического прокси, которые не могут быть сериализованы.]
Отсутствие ленивой загрузки в WebApi прекрасен, поскольку у вас нет постоянного соединения, и вы все равно запускали .ToList().
Ответ 4
Я просто отключил прокси-классы по необходимости:
// GET: ALL Employee
public IEnumerable<DimEmployee> Get()
{
using (AdventureWorks_MBDEV_DW2008Entities entities = new AdventureWorks_MBDEV_DW2008Entities())
{
entities.Configuration.ProxyCreationEnabled = false;
return entities.DimEmployees.ToList();
}
}
Ответ 5
Это помогло мне:
Добавьте следующий код в Application_Start
функцию Global.asax.cs
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters
.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
Ответ 6
В моем случае возвращаемый объект имеет свойство внутри него с типом, у которого не было конструктора без аргументов/по умолчанию. Добавив конструктор нулевого аргумента к этому типу, объект может быть успешно сериализован.