3
votes

I'm trying to use a WebApi to get a list of Employees from my data base, using this code: This is the code of my client MVC Application:

        string u = "http://localhost:1411/api/EmployeeAPI";
        Uri uri = new Uri(u);

        HttpClient httpClient = new HttpClient();

        Task<HttpResponseMessage> response = httpClient.GetAsync(uri);

        Task.WaitAll(response);

        HttpResponseMessage resposta = response.Result;

        var msg = resposta.Content.ReadAsStringAsync().Result;

        Employee[] employees = JsonConvert.DeserializeObject<Employee[]>(msg);

        return View(employees);

And this is the code of my WebAPI:

    public IEnumerable<Employee> GetEmployees()
    {
        return db.Employees.AsEnumerable();
    }

But this error keeps popping up and I can't understand why:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'DataAccess.Employee[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'Message', line 1, position 11.

My Employee Class:

namespace DataAccess
{
    using System;
    using System.Collections.Generic;

    public partial class Employee
    {
        public Employee()
        {
            this.Products = new HashSet<Product>();
        }

        public int EmployeeId { get; set; }
        public string Title { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public byte[] rowguid { get; set; }
        public System.DateTimeOffset ModifiedDate { get; set; }

        public virtual ICollection<Product> Products { get; set; }
    }
}

The Json output I'm not really sure how to get it

The msg variable content:

My msg variable returns

"{\"Message\":\"An error has occurred.\",\"ExceptionMessage\":\"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; 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.ProductSubCategory_9EC9A3706390DE6A3B51F713F0DDAC2162AFB5B3FAB8F8587C9A865333A7729A'. Path '[0].Products[0].ProductSubCategory.ProductCategory.ProductSubCategories'.\",\"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, IWrappedCollection 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.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, IWrappedCollection 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.SerializeList(JsonWriter writer, IWrappedCollection 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)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClassd.b__c()\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)\"}}"

2
First thing to do: separate the WebAPI part from the client part; fetch the JSON and check whether or not it makes sense. If it does, hard-code it into a small client program to isolate just this problem.Jon Skeet
Can you post the JSON output that cannot be deserialized?keiv.fly
Show us your JSON and your Employee classYuval Itzchakov
If seems that the JSON returned is a representation of a single object not array of employees.brainless coder
I updated the post so it has the employee class....the Json i not sure where to get itFrancisco Brito

2 Answers

2
votes

The best way to stop that error from occuring is:

In your WebApi project go to the App_Start folder and add to the WebApiConfig this four lines of code:

config.EnableSystemDiagnosticsTracing();
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
config.Formatters.Remove(config.Formatters.XmlFormatter);

and make sure you have instaled the Json nuget package

5
votes

Read the error;

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'DataAccess.Employee[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

 var msg = resposta.Content.ReadAsStringAsync().Result;

 Employee[] employees = JsonConvert.DeserializeObject<Employee[]>(msg);

You need to make sure above "msg" is an actual JSONArray.

{ "key" : "Value" }

is a JSONObject,

[{ "key" : "Value" }]

is a JSONArray.