C#Newtonsoft.Json.Linq.JValue始终返回Int64

我正在使用Newtonsoft.Json程序集将Json字符串反序列化为动态对象(ExpandoObject)。我遇到的问题是int值始终以我期望的Int32形式返回为Int64。该代码可以在下面看到。

namespace Serialization

{

using System;

using System.Collections.Generic;

using System.Dynamic;

using System.Linq;

using Newtonsoft.Json;

using Newtonsoft.Json.Linq;

public static class JsonSerializer

{

#region Public Methods

public static string Serialize(dynamic obj)

{

return JsonConvert.SerializeObject(obj);

}

public static dynamic Deserialize(string s)

{

var obj = JsonConvert.DeserializeObject(s);

return obj is string ? obj as string : Deserialize((JToken)obj);

}

#endregion

#region Methods

private static dynamic Deserialize(JToken token)

{

// FROM : http://blog.petegoo.com/archive/2009/10/27/using-json.net-to-eval-json-into-a-dynamic-variable-in.aspx

// Ideally in the future Json.Net will support dynamic and this can be eliminated.

if (token is JValue) return ((JValue)token).Value;

if (token is JObject)

{

var expando = new ExpandoObject();

(from childToken in token

where childToken is JProperty

select childToken as JProperty).ToList().

ForEach(property => ((IDictionary<string, object>)expando).Add(property.Name, Deserialize(property.Value)));

return expando;

}

if (token is JArray)

{

var items = new List<object>();

foreach (var arrayItem in ((JArray)token)) items.Add(Deserialize(arrayItem));

return items;

}

throw new ArgumentException(string.Format("Unknown token type '{0}'", token.GetType()), "token");

}

#endregion

}

}

通常我不会注意到这一点,但是这个特殊的int被用于某种类型检查的反映,并且失败了。任何想法为什么会发生这种情况将不胜感激。

回答:

释义:

  • 作者有意选择将所有int都返回,Int64以避免溢出错误,并且检查起来更容易(对于Json.NET内部而言,不是您自己)
  • 您可以使用自定义转换器(如链接答案中发布的转换器)来解决此问题。

这是一个真正的通用转换器;不能完全确定CanConvert支票,但对我有用的重要部分是允许typeof(object)

/// <summary>

/// To address issues with automatic Int64 deserialization -- see https://stackoverflow.com/a/9444519/1037948

/// </summary>

public class JsonInt32Converter : JsonConverter

{

#region Overrides of JsonConverter

/// <summary>

/// Only want to deserialize

/// </summary>

public override bool CanWrite { get { return false; } }

/// <summary>

/// Placeholder for inheritance -- not called because <see cref="CanWrite"/> returns false

/// </summary>

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

{

// since CanWrite returns false, we don't need to implement this

throw new NotImplementedException();

}

/// <summary>

/// Reads the JSON representation of the object.

/// </summary>

/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param><param name="objectType">Type of the object.</param><param name="existingValue">The existing value of object being read.</param><param name="serializer">The calling serializer.</param>

/// <returns>

/// The object value.

/// </returns>

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

{

return (reader.TokenType == JsonToken.Integer)

? Convert.ToInt32(reader.Value) // convert to Int32 instead of Int64

: serializer.Deserialize(reader); // default to regular deserialization

}

/// <summary>

/// Determines whether this instance can convert the specified object type.

/// </summary>

/// <param name="objectType">Type of the object.</param>

/// <returns>

/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.

/// </returns>

public override bool CanConvert(Type objectType)

{

return objectType == typeof(Int32) ||

objectType == typeof(Int64) ||

// need this last one in case we "weren't given" the type

// and this will be accounted for by `ReadJson` checking tokentype

objectType == typeof(object)

;

}

#endregion

}

以上是 C#Newtonsoft.Json.Linq.JValue始终返回Int64 的全部内容, 来源链接: utcz.com/qa/401818.html

回到顶部