0

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.

7
  • what are you trying to do? Commented Mar 12, 2017 at 20:02
  • I'm trying to fetch some user information from a JWT. Commented Mar 12, 2017 at 20:10
  • Can you paste the full payload you are sending Commented Mar 12, 2017 at 20:15
  • OK, so the exception is not being thrown by JObject.Parse(). It's being thrown by JWT.JsonWebToken.Decode() which is, internally, also using Json.NET. Is there any chance your JSON string was escaped into a single string containing embedded JSON? That could account for the error. Commented Mar 13, 2017 at 5:04
  • @dbc Oh, that's interesting. These are the only two methods in my application that operate on the JSON - outside of these, it's passed around either as a JWT or as an unserialized/deserialized object - so I think what you're describing would have to occur within the code I've provided, and as far as I can tell these operations are supposed to be essentially symmetrical. Commented Mar 13, 2017 at 11:08

3 Answers 3

1

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;
}
Sign up to request clarification or add additional context in comments.

Comments

0

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.

3 Comments

Thank you, but I'm still getting a JsonSerializationException when trying to deserialize.
Is your json in the format I have in my answer or a different format? And what error are you getting?
It's identical to the JSON in your answer, since I added the Formatting.Indented argument to the JsonConvert.SerializeObject() call. The error is the same as in my original post.
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.