为什么在尝试使用JsonConvert.DeserializeObject()时会出现JsonSerializationException?

时间:2017-03-12 20:00:03

标签: c# .net json json.net

我一直无法弄清楚JsonConvert.DeserializeObject()抛出此异常的原因。它发生在我的ReadJwt()方法中。我在这里也包含了我的CreateJwt()方法,以防万一,但我在其生成的JSON字符串中看不到任何语法错误。

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

以下是例外:

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.

InnerException如下:

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

我已经查看了类似问题的答案,但似乎对我的案例没什么帮助。关于如何解决这个问题的任何想法?如果我应该提供更多信息,请告诉我。

谢谢!

编辑:@dbc请求了更多的异常细节。

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: 

我正在使用JSON Web Token (JWT) Portable Implementation for .NET 4.5+进行JSON网络令牌生成和编码。

3 个答案:

答案 0 :(得分:1)

我想到了C#中JWT编码/解码方法接受/返回词典的谨慎态度,因为JSON不是.NET的原生。当然,结果JWT.JsonWebToken.Encode()根本不期望JSON字符串,而是表示有效负载的对象。因此,JWT出现格式错误,导致JWT.JsonWebToken.Decode()方法抛出JsonSerializationException。我将来在阅读文档时需要密切关注。

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

答案 1 :(得分:0)

这是你的JSON:

{
   "id": 8,

   "användarnamn": "test123",

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

使用我的回答here为其创建一个C#类。它将产生一个这样的类:

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

以下是如何对其进行反序列化:

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

以下是序列化的方法:

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

顺便提一下,如果你想使用我的答案,你需要NewtonSoft NuGet包。

答案 2 :(得分:0)

我将您的json字符串复制到文本文件中,并按如下方式成功反序列化:

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

请注意,Rootobject是通过复制json字符串并使用Edit&gt;粘贴它来生成的。选择性粘贴&gt; Paster JSON作为visual studio中的类。