Ag Bengip
Ag Bengip

Reputation: 11

Why am I getting a JsonSerializationException when trying to use JsonConvert.DeserializeObject()?

I've been having trouble figuring out why this exception is being thrown by JsonConvert.DeserializeObject(). It happens in my ReadJwt() method. I've also included my CreateJwt() method here, just in case, but I can't see any syntax errors in the JSON string it generates.

public static string CreateJwt(TokenObject input) {
    string key = "This key is fake";
    string json = JsonConvert.SerializeObject(input, Formatting.Indented);
    string jwt = JsonWebToken.Encode(json, key, JwtHashAlgorithm.HS256);
    return jwt;
}

public static TokenObject ReadJwt(string jwt) {
    string key = "This key is fake";
    return JsonConvert.DeserializeObject<TokenObject>
        (JsonWebToken.Decode(jwt, key));
}

Here's the exception:

An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code

Additional information: Error converting value "{

  "id": 8,

  "användarnamn": "test123",

  "utgång": "2017-03-19T19:28:00.5493447Z"

}" to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'. Path '', line 1, position 110.

The InnerException is as follows:

Could not cast or convert from System.String to System.Collections.Generic.Dictionary`2[System.String,System.Object].

I've looked at answers to similar questions, but nothing seems helpful to my case. Any ideas on how to solve this? Let me know if I should provide more information.

Thank you!

EDIT: @dbc requested more exception details.

Newtonsoft.Json.JsonSerializationException was unhandled by user code
  HResult=-2146233088
  Message=Error converting value "{
  "id": 8,
  "användarnamn": "test123",
  "utgång": "2017-03-19T21:15:27.3951877Z"
}" to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'. Path '', line 1, position 110.
  Source=Newtonsoft.Json
  StackTrace:
       vid Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
       vid Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
       vid Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
       vid Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
       vid Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
       vid Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
       vid Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
       vid Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
       vid JWT.DefaultJsonSerializer.Deserialize[T](String json)
       vid JWT.JsonWebToken.Decode(String token, Byte[] key, Boolean verify)
       vid JWT.JsonWebToken.Decode(String token, String key, Boolean verify)
       vid Webbchat.Controllers.HomeController.LäsJwt(String jwt) i c:\Users\Gustaf\Documents\Visual Studio 2013\Projects\Webbchat\Webbchat\Controllers\HomeController.cs:rad 66
       vid Webbchat.Controllers.HomeController.HämtaMeddelanden(String token, Int32 sistaId) i c:\Users\Gustaf\Documents\Visual Studio 2013\Projects\Webbchat\Webbchat\Controllers\HomeController.cs:rad 169
       vid lambda_method(Closure , ControllerBase , Object[] )
       vid System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       vid System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       vid System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       vid System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod()
       vid System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
       vid System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
       vid System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
       vid System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag)
       vid System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
       vid System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
       vid System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
  InnerException: System.ArgumentException
       HResult=-2147024809
       Message=Could not cast or convert from System.String to System.Collections.Generic.Dictionary`2[System.String,System.Object].
       Source=Newtonsoft.Json
       StackTrace:
            vid Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
            vid Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
            vid Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
       InnerException: 

I am using JSON Web Token (JWT) Portable Implementation for .NET 4.5+ for JSON web token generation and encoding.

Upvotes: 0

Views: 6927

Answers (3)

Ag Bengip
Ag Bengip

Reputation: 11

I thought about how it would be prudent for JWT encoding/decoding methods in C# to accept/return dictionaries, since JSON isn't native to .NET. Sure enough, turns out JWT.JsonWebToken.Encode() doesn't expect a JSON string at all, but an object representing the payload. Therefore the JWT came out malformed, causing the JWT.JsonWebToken.Decode() method to throw a JsonSerializationException. I'll need to pay closer attention when reading the documentation in the future.

public static string CreateJwt(TokenObject input) {
    string key = "This key is fake";
    string jwt = JsonWebToken.Encode(input, key, JwtHashAlgorithm.HS256);
    return jwt;
}

public static TokenObject ReadJwt(string jwt) {
    string key = "This key is fake";
    TokenObject output = JsonWebToken.DecodeToObject(jwt, key) as TokenObject;
    return output;
}

Upvotes: 1

Mahdi
Mahdi

Reputation: 3349

I copied your json string into a text file and successfully deserialized it as follows:

string json = File.ReadAllText(@"C:\MyStuff\json.txt", Encoding.GetEncoding("iso-8859-1"));
var test = JsonConvert.DeserializeObject<Rootobject>(json);

Note that the Rootobject is generated by copying the json string and pasting it using Edit > Paste Special > Paster JSON as Classes in visual studio.

Upvotes: 0

CodingYoshi
CodingYoshi

Reputation: 27009

This is your JSON:

{
   "id": 8,

   "användarnamn": "test123",

   "utgång": "2017-03-19T19:28:00.5493447Z"
}

Create a C# class for that using my answer here. It will produce a class like this:

public class Rootobject
{
  public int id { get; set; }
  public string användarnamn { get; set; }
  public DateTime utgång { get; set; }
}

And here is how to deserialize it:

Rootobject deserialized = 
    JsonConvert.DeserializeObject<Rootobject>("Your JSON");

Here is how to serialize it:

var ro = new Rootobject();
// set properties here
var serialized = JsonConvert.SerializeObject(ro);

By the way you need the NewtonSoft NuGet package if you want to use my answer.

Upvotes: 0

Related Questions