Ошибка сериализации json

I have the following exception generated inconsistently but frequently:

System.Exception: Serialization error - One or more errors occurred., Unexpected character encountered while parsing value: <. Path '', line 0, position 0., System.AggregateException: One or more errors occurred. ---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Microsoft.AspNet.SignalR.Client.Transports.TransportHelper.b__1(String raw)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.b__17(Task`1 t)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.b__41(Task`1 t)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   **at Project.Services.NotificationService.SignalObjectToUser(Object data, String username, Boolean isTypingNotification)
---> (Inner Exception #0) Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.**
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Microsoft.AspNet.SignalR.Client.Transports.TransportHelper.b__1(String raw)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.b__17(Task`1 t)

The important bit:

**at Project.Services.NotificationService.SignalObjectToUser(Object data, String username, Boolean isTypingNotification)
---> (Inner Exception #0) Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.**

My code there:

private void SignalObjectToUser(object data, string username, bool isTypingNotification = false) {
        try {
            _hubConnection = new HubConnection(_baseUrl);
            _hubConnection.CookieContainer = new CookieContainer();
            _hubConnection.CookieContainer.Add(_cookie);
            _hubProxy = _hubConnection.CreateHubProxy("appHub");
            _hubConnection.Start().Wait();
            string serialized = null;
            try {
                List<string> errors = new List<string>();
                serialized = JsonConvert.SerializeObject(data, new JsonSerializerSettings() {
                    Error = delegate(object sender, ErrorEventArgs args) {
                        errors.Add(args.ErrorContext.Error.Message);
                        args.ErrorContext.Handled = true;
                        Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Delegated serialization error - " + args.ErrorContext.Error.Message));
                    }
                });
                _hubProxy.Invoke((isTypingNotification ? "SendTypingNotification" : "SendClientNotification"), serialized, username).Wait();
            }
            catch (Exception exception) {
                Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Serialization error - " + exception.Message + ", " + exception.InnerException.Message + ", " + exception.ToString()));
                throw new Exception("Messaging Error");
            }
        }
        catch (Exception e) {
            Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Serialization error - " + e.Message + ", " + e.InnerException.Message + ", " + e.ToString()));
            throw new Exception("Messaging Error");
        }
    }

I’m trying to figure out what exactly is causing this issue though. I don’t know what key/value pair is generating the exception. How can I gather more instructive details here?

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();
    }
}

chakeda's user avatar

chakeda

1,5411 gold badge18 silver badges39 bronze badges

asked Apr 16, 2014 at 2:56

CampDev's user avatar

4

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!

Markus's user avatar

Markus

20.7k4 gold badges31 silver badges55 bronze badges

answered Mar 1, 2015 at 1:08

Lucas Roselli's user avatar

Lucas RoselliLucas Roselli

2,8001 gold badge15 silver badges18 bronze badges

5

When it comes to returning data back to the consumer from Web Api (or any other web service for that matter), I highly recommend not passing back entities that come from a database. It is much more reliable and maintainable to use Models in which you have control of what the data looks like and not the database. That way you don’t have to mess around with the formatters so much in the WebApiConfig. You can just create a UserModel that has child Models as properties and get rid of the reference loops in the return objects. That makes the serializer much happier.

Also, it isn’t necessary to remove formatters or supported media types typically if you are just specifying the «Accepts» header in the request. Playing around with that stuff can sometimes make things more confusing.

Example:

public class UserModel {
    public string Name {get;set;}
    public string Age {get;set;}
    // Other properties here that do not reference another UserModel class.
}

answered Apr 16, 2014 at 3:12

jensendp's user avatar

jensendpjensendp

2,13515 silver badges15 bronze badges

7

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);

answered Jan 14, 2016 at 18:48

Bimal Das's user avatar

Bimal DasBimal Das

1,8835 gold badges28 silver badges53 bronze badges

2

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();
    }
}

answered Sep 16, 2016 at 14:21

Aykut's user avatar

AykutAykut

1191 silver badge3 bronze badges

2

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);

answered Mar 23, 2018 at 13:28

aemre's user avatar

aemreaemre

2,3212 gold badges17 silver badges19 bronze badges

1

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();

Donut's user avatar

Donut

109k20 gold badges133 silver badges146 bronze badges

answered Apr 9, 2015 at 13:40

Kasper Jensen's user avatar

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;
  }
}

answered Jan 12, 2018 at 4:31

Er Suman G's user avatar

Er Suman GEr Suman G

5515 silver badges12 bronze badges

1

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!

answered Oct 24, 2014 at 17:20

Alex's user avatar

AlexAlex

1582 silver badges7 bronze badges

2

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"));

answered Aug 12, 2016 at 11:24

Ogglas's user avatar

OgglasOgglas

60.3k36 gold badges320 silver badges412 bronze badges

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;

סטנלי גרונן's user avatar

סטנלי גרונן

2,90723 gold badges46 silver badges68 bronze badges

answered Jun 13, 2020 at 6:30

Sayyam abbasi's user avatar

Use AutoMapper…

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

answered Sep 4, 2015 at 4:30

Proximo's user avatar

ProximoProximo

6,15511 gold badges49 silver badges66 bronze badges

Use the following namespace:

using System.Web.OData;

Instead of :

using System.Web.Http.OData;

It worked for me

Mayuso's user avatar

Mayuso

1,2914 gold badges19 silver badges40 bronze badges

answered Nov 3, 2016 at 10:40

Harish K's user avatar

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();
        }
    }
    

barbsan's user avatar

barbsan

3,40811 gold badges21 silver badges28 bronze badges

answered Jun 13, 2019 at 5:55

MR.S's user avatar

MR.SMR.S

212 bronze badges

Use [Serializable] for class:

Example:

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

It worked for me!

answered Jul 22, 2019 at 16:48

Msxmania's user avatar

MsxmaniaMsxmania

532 silver badges9 bronze badges

1

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

Community's user avatar

answered Nov 16, 2016 at 7:07

Lapenkov Vladimir's user avatar

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>

answered May 5, 2015 at 13:27

Greg A's user avatar

Greg AGreg A

5314 silver badges9 bronze badges

1

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.

answered Dec 29, 2017 at 12:39

B Bhatnagar's user avatar

B BhatnagarB Bhatnagar

1,6864 gold badges22 silver badges35 bronze badges

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

answered Feb 19, 2018 at 12:21

Maytham Fahmi's user avatar

Maytham FahmiMaytham Fahmi

30.7k14 gold badges114 silver badges134 bronze badges

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:

answered Apr 24, 2019 at 9:36

Gül Eda Aydemir's user avatar

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

answered Jul 28, 2019 at 11:47

Yogesh Dangre's user avatar

1

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.

answered Oct 14, 2015 at 14:49

marshall's user avatar

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

answered Nov 15, 2017 at 15:52

Vanice's user avatar

VaniceVanice

6765 silver badges15 bronze badges

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.

answered Apr 30, 2019 at 20:27

William Hou's user avatar

William HouWilliam Hou

1,13113 silver badges17 bronze badges

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’.»

answered May 30, 2019 at 14:46

Manuel Sansone's user avatar

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.

answered Jun 5, 2019 at 10:24

Catalyst's user avatar

CatalystCatalyst

4655 silver badges13 bronze badges

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; }

answered Apr 3, 2020 at 18:21

Hadi R.'s user avatar

Hadi R.Hadi R.

4033 silver badges12 bronze badges

Comments

@AlexeyKhrenov

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 16, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 16, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

NOTE: we had to use UTF-8 (instead of Encoding.Default) because otherwise
the tests (committed from my macOS) would fail on Windows CI. Don't ask
me why, I hate encodings too.

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 16, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

NOTE: we had to use ASCII (instead of Encoding.Default) because otherwise
the tests (committed from my macOS) would fail on Windows CI (UTF-8 would
fail too because of [3]0. Don't ask me why, I hate encodings too.

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 16, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

NOTE: we had to use Base64 because using any of the System.Text encodings
(like Encoding.Default, ASCII, UTF-8 or UTF-7) would make the tests fail
fail in weird ways (or only pass for certain OSs, e.g. see [3]). Don't
ask me why, I hate encodings too.

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 20, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 20, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Dec 21, 2020

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-default-encoding-based-string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Jan 4, 2021

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-base64string format.

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

knocte

added a commit
to nblockchain/geewallet
that referenced
this issue

Jan 4, 2021

@knocte

JSON deserialization of exceptions is extremely broken in JSON.NET [1]
(and even in System.Text.Json [2]), so let's use a hybrid between binary
serialization and JSON serialization: it will have a JSON part that hints
about the most important human-readable details, but it will use a JSON
element to marshall in binary-to-base64string format (I decided to use
base64string after having many issues, e.g. [3], with UTF8 and other
encodings).

(I could have written a JsonConverter for this, but I was having trouble
finding one out there that someone else had written already, then I decided
to go for the simplest solution that I can write myself. I hate JSON type
converters anyway.)

[1] JamesNK/Newtonsoft.Json#801
[2] dotnet/runtime#43026
[3] https://stackoverflow.com/a/13674508/544947

simon-wacker

added a commit
to building-envelope-data/metabase
that referenced
this issue

Jul 13, 2021

@simon-wacker

@msftbot
msftbot
bot

locked as resolved and limited conversation to collaborators

Nov 22, 2021

How to fix the “typeerror object of type is not json serializable” error message?

In this article, we will guide you on how to troubleshoot this error message that gives you a headache.

The “python object of type is not json serializable” error is quite frustrating, especially if you’re familiar with it and don’t know how to fix it.

This article is indeed for you, so keep on reading because we will discuss what this error means and the root causes.

A JSON serializable refers to data that can be converted to a JSON format without any issues.

JSON stands for JavaScript Object Notation.

JSON is a widely used format for data exchange, particularly in web applications.

It can represent simple data types such as strings and numbers, as well as complex data types such as lists and dictionaries.

However, not all Python objects can be directly serialized to JSON.

If you encounter this error message, it means that you are attempting to convert an object of an unsupported type to JSON.

You’ll see in the table below how the native Python objects are translated to JSON.

Python JSON
list, tuple array
int, long, float number
dict object
str string
None null
True true
False false

What is “typeerror object of type is not json serializable”?

The “typeerror: object of type is not JSON serializable” is an error message that occurs when you try to serialize an object to JSON format, but the object type is not supported by the JSON encoder.

In a simple words, the object is not “JSON serializable”.

In addition to that, this error occurs when you try to serialize an object that is not JSON serializable using the json.dump() or json.dumps() method.

Why does this error “object of type is not json serializable” occur?

This error occurs for several reasons, such as:

  • The input data contains a data type that is not JSON serializable, such as sets, complex numbers, or custom objects.
  • The input data contains a circular reference, where two or more objects refer to each other in a way that forms an infinite loop.
  • The input data contains a datetime object that is not JSON serializable. Datetime objects need to be converted to a string format before they can be serialized to JSON.
  • The input data contains a NumPy array or other non-Python object that is not JSON serializable.
  • The input data contains a subclass of a built-in Python type that is not JSON serializable.
  • For example, if you define a custom class that inherits from the dict class, you need to ensure that the class is JSON serializable.
  • The input data contains a function or other callable object that is not JSON serializable.

How to fix “typeerror object of type is not json serializable”?

To fix this “python object of type is not json serializable” error, you need to either remove the non-serializable data from the input, convert it to a JSON-serializable data type, or use a custom function that can properly serialize the data.

Here are the following solutions you may use to resolve the “object of type is not json serializable” error message:

1. Remove non-serializable data from the input

You have define a remove_non_serializable function that removes any non-serializable data types and converts the set object to a list.

import json
from collections import OrderedDict

data = {
    'website': 'Itsourcecode',
    'Visits': 18000000,
    'Offers': {'free sourcecode and tutorials'}
}

def remove_non_serializable(obj):
    if isinstance(obj, set):
        return list(obj)
    return obj

json_data = json.dumps(OrderedDict((k, remove_non_serializable(v)) for k, v in data.items()))
print(json_data)

Output:

{"website": "Itsourcecode", "Visits": 18000000, "Offers": ["free sourcecode and tutorials"]}

2.Convert non-serializable data types to JSON-serializable types

In this example, the data dictionary contains a datetime object, which is not JSON-serializable.

So, we just define a json_serializable function that converts the datetime object to a string representation using the __str__() method.

import json
from datetime import datetime

data = {
    'website': 'Itsourcecode',
    'Visits': 18000000,
    'Offers': 'free sourcecode and tutorials',
    'dob': datetime.now()

}

def json_serializable(obj):
    if isinstance(obj, datetime):
        return obj.__str__()

print(json.dumps(data, default=json_serializable))

Then pass this function as the default parameter to the json.dumps() function, which converts the datetime object to a string representation and serializes the entire dictionary into JSON format.

Output:

{"website": "Itsourcecode", "Visits": 18000000, "Offers": "free sourcecode and tutorials", "dob": "2023-04-14 15:56:35.558356"}

3. Use custom function to handle non-serializable objects

You have to define a custom encoder that can handle non-serializable data types.

You can do this by subclassing the json.JSONEncoder class and overriding the default() method to provide a custom serialization method for your non-serializable data.

import json

# Define a custom encoder class
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, set):
            return list(obj)
        elif isinstance(obj, complex):
            return {'real': obj.real, 'image': obj.imag}
        else:
            return super().default(obj)

# Define a dictionary with non-serializable data
my_dict = {'my_set': {1, 2, 3}, 'my_complex': 1 + 2j}

# Serialize the dictionary with the custom encoder
serialized_data = json.dumps(my_dict, cls=MyEncoder)
print(serialized_data)

Output:

{"my_set": [1, 2, 3], "my_complex": {"real": 1.0, "image": 2.0}}

Conclusion

By executing all the effective solutions for the “typeerror object of type is not json serializable” that this article has already provided above, it will help you resolve the error.

We are hoping that this article provides you with sufficient solutions.

You could also check out other “typeerror” articles that may help you in the future if you encounter them.

  • Typeerror cannot read property ‘map’ of undefined
  • Typeerror cannot set properties of undefined
  • Typeerror: ‘column’ object is not callable

Thank you very much for reading to the end of this article.

Json.NET supports error handling during serialization and deserialization. Error handling lets
you catch an error and choose whether to handle it and continue with serialization or let the error
bubble up and be thrown in your application.

Error handling is defined through two methods:
the Error event on JsonSerializer and the OnErrorAttribute.

Error Event

The Error event is an event handler found on JsonSerializer. The error event is raised whenever an
exception is thrown while serializing or deserialing JSON. Like all settings found on JsonSerializer
it can also be set on JsonSerializerSettings and passed to the serialization methods on JsonConvert.

List<string> errors = new List<string>();
 
List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
  ""2009-09-09T00:00:00Z"",
  ""I am not a date and will error!"",
  [
    1
  ],
  ""1977-02-20T00:00:00Z"",
  null,
  ""2000-12-01T00:00:00Z""
]",
  new JsonSerializerSettings
    {
      Error = delegate(object sender, ErrorEventArgs args)
        {
          errors.Add(args.ErrorContext.Error.Message);
          args.ErrorContext.Handled = true;
        },
      Converters = { new IsoDateTimeConverter() }
    });
 
// 2009-09-09T00:00:00Z
// 1977-02-20T00:00:00Z
// 2000-12-01T00:00:00Z
 
// The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
// Unexpected token parsing date. Expected String, got StartArray.
// Cannot convert null value to System.DateTime.

In this example we are deserializing a JSON array to a collection of DateTimes. On the JsonSerializerSettings
a handler has been assigned to the Error event which will log the error message and mark the error as handled.

The result of deserializing the JSON is three successfully deserialized dates and three error messages:
one for the badly formatted string, «I am not a date and will error!», one for the nested JSON array and one
for the null value since the list doesn’t allow nullable DateTimes. The event handler has logged these messages
and Json.NET has continued on deserializing the JSON because the errors were marked as handled.

One thing to note with error handling in Json.NET is that an unhandled error will bubble up and raise the event
on each of its parents, e.g. an unhandled error when serializing a collection of objects will be raised twice,
once against the object and then again on the collection. This will let you handle an error either where it
occurred or on one of its parents.

JsonSerializer serializer = new JsonSerializer();
serializer.Error += delegate(object sender, ErrorEventArgs args)
  {
    // only log an error once
    if (args.CurrentObject == args.ErrorContext.OriginalObject)
      errors.Add(args.ErrorContext.Error.Message);
  };

If you aren’t immediately handling an error and only want to perform an action against it once then
you can check to see whether the ErrorEventArg’s CurrentObject is equal to the OriginalObject.
OriginalObject is the object that threw the error and CurrentObject is the object that the event is being raised
against. They will only equal the first time the event is raised against the OriginalObject.

OnErrorAttribute

The OnErrorAttribute works much like the other .NET serialization attributes that Json.NET supports.
To use it you simply place the attribute on a method which takes the correct parameters: a StreamingContext and a ErrorContext.
The name of the method doesn’t matter.

public class PersonError
{
  private List<string> _roles;
 
  public string Name { get; set; }
  public int Age { get; set; }
  public List<string> Roles
  {
    get
    {
      if (_roles == null)
        throw new Exception("Roles not loaded!");
 
      return _roles;
    }
    set { _roles = value; }
  }
  public string Title { get; set; }
 
  [OnError]
  internal void OnError(StreamingContext context, ErrorContext errorContext)
  {
    errorContext.Handled = true;
  }
}

In this example accessing the the Roles property will throw an exception when no roles have
been set. The HandleError method will set the error when serializing Roles as handled and allow Json.NET to continue
serializing the class.

PersonError person = new PersonError
  {
    Name = "George Michael Bluth",
    Age = 16,
    Roles = null,
    Title = "Mister Manager"
  };
 
string json = JsonConvert.SerializeObject(person, Formatting.Indented);
 
Console.WriteLine(json);
//{
//  "Name": "George Michael Bluth",
//  "Age": 16,
//  "Title": "Mister Manager"
//}

Понравилась статья? Поделить с друзьями:
  • Ошибка сериал франция трейлер
  • Ошибка сетевой адаптер не обнаружен
  • Ошибка сериал франция скачать торрент
  • Ошибка сетевое подключение не существует
  • Ошибка сериал пакистан