问题描述
我反序列化一些属性到词典<字符串对象>
。
I'm deserializing some properties to a Dictionary<string, object>
.
当我反序列化一些JSON,它填充词典
与的Int64
对象,而不是的Int32
。我想它选择的Int32
作为默认也知道我可以有JavaScript的Numerics的,将溢出的转换。在这种情况下抛出一个异常是完全可以接受的。
When I deserialize some json, it populates the Dictionary
with Int64
objects rather than Int32
. I would like it to choose Int32
as the default well knowing that I could have javascript Numerics that would overflow on conversion. Throwing an exception in that case would be entirely acceptable.
有没有什么办法来实现这一目标?我希望的是可以实施,并添加到 JsonSerializer
一些不错的属性或一个方便的接口。我担心,我必须在内心深处进入Json.NET的深处。
Is there any way to achieve that? I'm hoping for some nice attributes or a convenient interface that could be implemented and added to the JsonSerializer
. And I fear that I have to go deep down into the depths of Json.NET.
基本上我想有一些方法来控制已知类型的对象,因此我能得到的,而不是的Int64
和的Int32
DateTime是否
而不是字符串
。
Basically I would like to have some way to control the known types for the objects so that I could get Int32
's instead of Int64
and DateTimes
instead of Strings
.
推荐答案
据我所知,有没有内置的方式来做到这一点。
As far as I know, there is no built-in way to do that.
有是一个关于这个问题,但它已被关闭。
从笔者对这个问题的一些意见:
There was an issue on this subject, but it has been closed.Some comments from the author on the issue:
Json.NET默认读取整数值作为Int64的,因为没有办法要知道的值是否应的Int32或Int64类型,并且Int64的是不太可能溢出。对于一个类型的属性解串器知道到的Int64转换为的Int32,而是因为你的财产是无类型你得到一个Int64。 [...]这只是Json.NET有工作的方式。
课的最容易的解决办法是改变类型词典<字符串,整数>
,但我想你是不是只读数字和因此被套牢对象
The easiest solution would of coure be to change the type to Dictionary<string, int>
, but I suppose you are not only reading numerics and thus are stuck with object
.
另一种选择是要么使用并手动转换的的Int64
s到的Int32
或创建自己的的并直接控制(默认)序列
Another option would be to either use Serialization Callbacks and manually convert those Int64
s to Int32
or create your own JsonConverter and directly control the (de-)serialization.
编辑:。STRONG>我创建了一个小例子更具体
I created a little example to be more specific.
下面是一个非常基本的转换器,只用你的specifc字典作品:
Here is a very basic converter that only works with your specifc Dictionary:
public class Int32Converter : JsonConverter {
public override bool CanConvert(Type objectType) {
// may want to be less concrete here
return objectType == typeof(Dictionary<string, object>);
}
public override bool CanWrite {
// we only want to read (de-serialize)
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
// again, very concrete
Dictionary<string, object> result = new Dictionary<string, object>();
reader.Read();
while (reader.TokenType == JsonToken.PropertyName) {
string propertyName = reader.Value as string;
reader.Read();
object value;
if (reader.TokenType == JsonToken.Integer)
value = Convert.ToInt32(reader.Value); // convert to Int32 instead of Int64
else
value = serializer.Deserialize(reader); // let the serializer handle all other cases
result.Add(propertyName, value);
reader.Read();
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
// since CanWrite returns false, we don't need to implement this
throw new NotImplementedException();
}
}
您可以使用属性来装点成员与转换器或以一个(默认)序列化方法。这里就是我用了一个属性的例子:
You can either use attributes to decorate members with your converter or pass it as parameter to a (de-)serialize method. Here's an example where I used an attribute:
[JsonObject]
public class MyObject {
[JsonConverter(typeof(Int32Converter))]
public Dictionary<string, object> Properties { get; set; }
}
这是我用来测试的实现代码:
And here's the code I used to test the implementation:
class Program {
static void Main(string[] args) {
MyObject test = new MyObject();
test.Properties = new Dictionary<string, object>() { { "int", 15 }, { "string", "hi" }, { "number", 7 } };
Print("Original:", test);
string json = JsonConvert.SerializeObject(test);
Console.WriteLine("JSON:\n{0}\n", json);
MyObject parsed = JsonConvert.DeserializeObject<MyObject>(json);
Print("Deserialized:", parsed);
}
private static void Print(string heading, MyObject obj) {
Console.WriteLine(heading);
foreach (var kvp in obj.Properties)
Console.WriteLine("{0} = {1} of {2}", kvp.Key, kvp.Value, kvp.Value.GetType().Name);
Console.WriteLine();
}
}
没有转换器,其结果将是:
Without the converter, the result would be:
Deserialized:
int = 15 of Int64
string = hi of String
number = 7 of Int64
和与转换器,它是:
Deserialized:
int = 15 of Int32
string = hi of String
number = 7 of Int32
这篇关于如何更改为数字反序列化的默认类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!