[c#] Failed to serialize the response in Web API with Json

I am working with ASP.NET MVC 5 Web Api. I want consult all my users.

I wrote api/users and I receive this:

"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'"

In WebApiConfig, already I added these lines:

HttpConfiguration config = new HttpConfiguration();
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

But it still doesn't work.

My function for return data is this:

public IEnumerable<User> GetAll()
{
    using (Database db = new Database())
    {
        return db.Users.ToList();
    }
}

This question is related to c# asp.net json asp.net-web-api

The answer is


I resolved it using this code to WebApiConfig.cs file

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 
config.Formatters.Remove(config.Formatters.XmlFormatter);

Just put following lines in global.asax:

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

Import

using System.Data.Entity;

While all these answers above are correct, one may want to check the InnerException > ExceptionMessage.

If it says something like this "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.". This could be an issue because of default behavior of the EF.

By assigning LazyLoadingEnabled = false in your DbContext constructor will do the trick.

public class MyDbContext : DbContext
{
  public MyDbContext()
  {
    this.Configuration.LazyLoadingEnabled = false;
  }
}

For more detailed reading about EagerLoading and LazyLoading behavior of EF refer this MSDN Article.


Add the below line

this.Configuration.ProxyCreationEnabled = false;

Two way to use ProxyCreationEnabled as false.

  1. Add it inside of DBContext Constructor

    public ProductEntities() : base("name=ProductEntities")
    {
        this.Configuration.ProxyCreationEnabled = false;
    }
    

OR

  1. Add the line inside of Get method

    public IEnumerable<Brand_Details> Get()
    {
        using (ProductEntities obj = new ProductEntities())
        {
            this.Configuration.ProxyCreationEnabled = false;
            return obj.Brand_Details.ToList();
        }
    }
    

This is my error

I basically add one line which they are

  • entities.Configuration.ProxyCreationEnabled = false;

to UsersController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using UserDataAccess;

namespace SBPMS.Controllers
{
    public class UsersController : ApiController
    {


        public IEnumerable<User> Get() {
            using (SBPMSystemEntities entities = new SBPMSystemEntities()) {
                entities.Configuration.ProxyCreationEnabled = false;
                return entities.Users.ToList();
            }
        }
        public User Get(int id) {
            using (SBPMSystemEntities entities = new SBPMSystemEntities()) {
                entities.Configuration.ProxyCreationEnabled = false;
                return entities.Users.FirstOrDefault(e => e.user_ID == id);
            }
        }
    }
}

Here is my output:


Use AutoMapper...

public IEnumerable<User> GetAll()
    {
        using (Database db = new Database())
        {
            var users = AutoMapper.Mapper.DynamicMap<List<User>>(db.Users);
            return users;
        }
    }

Use the following namespace:

using System.Web.OData;

Instead of :

using System.Web.Http.OData;

It worked for me


public class UserController : ApiController
{

   Database db = new Database();

   // construction
   public UserController()
   {
      // Add the following code
      // problem will be solved
      db.Configuration.ProxyCreationEnabled = false;
   }

   public IEnumerable<User> GetAll()
    {
            return db.Users.ToList();
    }
}

You will have to define Serializer Formatter within WebApiConfig.cs available in App_Start Folder like

Adding config.Formatters.Remove(config.Formatters.XmlFormatter); // which will provide you data in JSON Format

Adding config.Formatters.Remove(config.Formatters.JsonFormatter); // which will provide you data in XML Format


There's also this scenario that generate same error:

In case of the return being a List<dynamic> to web api method

Example:

public HttpResponseMessage Get()
{
    var item = new List<dynamic> { new TestClass { Name = "Ale", Age = 30 } };

    return Request.CreateResponse(HttpStatusCode.OK, item);
}

public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}

So, for this scenario use the [KnownTypeAttribute] in the return class (all of them) like this:

[KnownTypeAttribute(typeof(TestClass))]
public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}

This works for me!


In case: If adding code to WebApiConfig.cs or Global.asax.cs doesn't work for you:

.ToList();

Add .ToList() function.

I tried out every solution but following worked for me:

var allShops = context.shops.Where(s => s.city_id == id)**.ToList()**;
return allShops;

I hope, it helps.


In my case I solved recreating the database. I made some changes in a model and launching Update-Database in Package Manager Console I got the following Error:

"The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Activities_dbo.Projects_ProjectId". The conflict occurred in database "TrackEmAllContext-20190530144302", table "dbo.Projects", column 'Id'."


My personal favorite: Just add the code below to App_Start/WebApiConfig.cs. This will return json instead of XML by default and also prevent the error you had. No need to edit Global.asax to remove XmlFormatter etc.

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

Given right answer is one way to go, however it is an overkill when you can fix it by one config settings.

Better to use it in the dbcontext constructor

public DbContext() // dbcontext constructor
            : base("name=ConnectionStringNameFromWebConfig")
{
     this.Configuration.LazyLoadingEnabled = false;
     this.Configuration.ProxyCreationEnabled = false;
}

Asp.Net Web API Error: The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'


To add to jensendp's answer:

I would pass the entity to a user created model and use the values from that entity to set the values in your newly created model. For example:

public class UserInformation {
   public string Name { get; set; }
   public int Age { get; set; }

   public UserInformation(UserEntity user) {
      this.Name = user.name;
      this.Age = user.age;
   }
}

Then change your return type to: IEnumerable<UserInformation>


in my case, it was fixed when I removed the virtual keyword before my navigation properties, I mean the reference tables. so I changed

public virtual MembershipType MembershipType { get; set; }

to:

public MembershipType MembershipType { get; set; }

Adding this in your Application_Start() method of Global.asax file should solve the problem

protected void Application_Start()
{
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
        .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters
        .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); 
// ...
}

METHOD 2: [Not recommended]
If you are working with EntityFramework, you can disable proxy in your DbContext class constructor. NOTE: this code wll be removed if you update the model

public class MyDbContext : DbContext
{
  public MyDbContext()
  {
    this.Configuration.ProxyCreationEnabled = false;
  }
}

If you are working with EF, besides adding the code below on Global.asax

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

Dont`t forget to import

using System.Data.Entity;

Then you can return your own EF Models

Simple as that!


Another case where I received this error was when my database query returned a null value but my user/view model type was set as non-nullable. For example, changing my UserModel field from int to int? resolved.


I don't like this code:

foreach(var user in db.Users)

As an alternative, one might do something like this, which worked for me:

var listOfUsers = db.Users.Select(r => new UserModel
                         {
                             userModel.FirstName = r.FirstName;
                             userModel.LastName = r.LastName;

                         });

return listOfUsers.ToList();

However, I ended up using Lucas Roselli's solution.

Update: Simplified by returning an anonymous object:

var listOfUsers = db.Users.Select(r => new 
                         {
                             FirstName = r.FirstName;
                             LastName = r.LastName;
                         });

return listOfUsers.ToList();

Visual Studio 2017 or 2019 is totally unthoughtful on this, because Visual Studio itself requires the output to be in json format, while Visual Studio's default format is "XmlFormat" (config.Formatters.XmlFormatter).

Visual Studio should do this automatically instead of giving developers so much trouble.

To correct this problem, go to the WebApiConfig.cs file, and add

var json = config.Formatters.JsonFormatter; json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; config.Formatters.Remove(config.Formatters.XmlFormatter);

after "config.MapHttpAttributeRoutes();" in the Register(HttpConfiguration config) method. This would allow your project to produce json output.


Use [Serializable] for class:

Example:

[Serializable]
public class UserModel {
    public string Name {get;set;}
    public string Age {get;set;}
}

It worked for me!


Solution that worked for me:

  1. Use [DataContract] for class and [DataMember] attributes for each property to serialize. This is enough to get Json result (for ex. from fiddler).

  2. To get xml serialization write in Global.asax this code:

    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;

  3. Read this article, it helped me to understand serialization: https://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

In my case I have had similar error message:

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.

But when I dig deeper in it, the issue was:

Type 'name.SomeSubRootType' with data contract name 'SomeSubRootType://schemas.datacontract.org/2004/07/WhatEverService' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

The way I solved by adding KnownType.

[KnownType(typeof(SomeSubRootType))]
public partial class SomeRootStructureType

This was solved inspired from this answer.

Reference: https://msdn.microsoft.com/en-us/library/ms730167(v=vs.100).aspx


Add this code to global.asax below on Application_Start:

Update from .Ignore to .Serialize . It must work.

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

This also happens when the Response-Type is not public! I returned an internal class as I used Visual Studio to generate me the type.

internal class --> public class

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to asp.net

RegisterStartupScript from code behind not working when Update Panel is used You must add a reference to assembly 'netstandard, Version=2.0.0.0 No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization How to use log4net in Asp.net core 2.0 Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state How to create roles in ASP.NET Core and assign them to users? How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() ASP.NET Core Web API Authentication Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0 WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to asp.net-web-api

Entity Framework Core: A second operation started on this context before a previous operation completed FromBody string parameter is giving null How to read request body in an asp.net core webapi controller? JWT authentication for ASP.NET Web API Token based authentication in Web API without any user interface Web API optional parameters How do I get the raw request body from the Request.Content object using .net 4 api endpoint How to use a client certificate to authenticate and authorize in a Web API HTTP 415 unsupported media type error when calling Web API 2 endpoint The CodeDom provider type "Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider" could not be located