Member 10371658 Ответов: 1

При получении записи произошла ошибка Web api 2


я попытался получить данные из базы данных, у меня есть контроллер продукта и две сущности связаны(категория и поставщик) с сущностью продукта.

произошла ошибка:
URL-адрес: http://localhost:43938/api/products

Ошибка:

{"Message":"An error has occurred.","ExceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'text/html; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.Product_38D1FFB7107F8535EF889B819ADB900579A7E9B61EEF00299400B8FA6949CA63'. Path '[0].Category.Products'.","ExceptionType":"Newtonsoft.Json.JsonSerializationException","StackTrace":" at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference(JsonWriter writer, Object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()"}}


Что я уже пробовал:

метод веб-api:

[Route("api/Products", Name = "Products")]
       public IQueryable<Product> GetProducts()
       {
           return db.Products;
       }



Созданный класс Entity framework:

public partial class Product
   {
       public int PId { get; set; }
       public string ProductName { get; set; }
       public Nullable<decimal> Price { get; set; }
       public Nullable<int> SId { get; set; }
       public Nullable<int> CId { get; set; }

       public virtual Category Category { get; set; }
       public virtual Supplier Supplier { get; set; }
   }



WebApiConfig.в CS
config.Formatters.JsonFormatter.SupportedMediaTypes
  .Add(new MediaTypeHeaderValue("text/html"));
      }

1 Ответов

Рейтинг:
2

David_Wimbley

Итак, во-первых, почему вы делаете запрос и ожидаете tex/html, когда web api вернет json?

Таким образом, если оставить в стороне несоответствие форматирования, некоторые из проблем заключаются в том, что вы возвращаете сущности непосредственно из своей БД через веб-API. Ваш класс продуктов, вероятно, имеет сложную связь с каким-то другим классом/таблицей в вашем приложении. Пример: продукты привязаны к заказам или что-то в этом роде.

У вас есть несколько вариантов:

1) вместо того, чтобы возвращать сущность, верните класс модели, над которым у вас есть полный контроль
2) Измените свой веб-api global. asx, чтобы добавить

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
            GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);


Обратите внимание на то, что вы удаляете XML-форматер. Возможно, для вас это не имеет значения, но имейте это в виду.

3) или добавьте следующий фрагмент кода локально в само действие Web API. Я еще не пробовал это сделать, но быстрый поиск в google по вашей проблеме возвращает тонны результатов, в которые было включено это предложение.

context.Configuration.ProxyCreationEnabled = false;


Member 2719936

Я сделал так, как было предложено
Глобальная конфигурация.Конфигурация.Форматеры.JsonFormatter.Сериализаторы.ReferenceLoopHandling = Newtonsoft. Json.Обращение с ссылками.Сериализовать;
Глобальная конфигурация.Конфигурация.Форматеры.Удалить(GlobalConfiguration.Конфигурация.Форматеры.XmlFormatter);

Но я все еще получаю ту же ошибку. Что-нибудь еще добавить/изменить?