如何更改为数字反序列化的默认类型? [英] How do I change the default Type for Numeric deserialization?

查看:163
本文介绍了如何更改为数字反序列化的默认类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我反序列化一些属性到词典<字符串对象>

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有工作的方式。

Json.NET by default reads integer values as Int64 because there is no way to know whether the value should be Int32 or Int64, and Int64 is less likely to overflow. For a typed property the deserializer knows to convert the Int64 to a Int32 but because your property is untyped you are getting an Int64. [...] It is just the way Json.NET has to work.

课的最容易的解决办法是改变类型词典<字符串,整数> ,但我想你是不是只读数字和因此被套牢对象

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 或创建自己的Contract解析器 JsonConverter 并直接控制(默认)序列

Another option would be to either use Serialization Callbacks and manually convert those Int64s to Int32 or create your own Contract Resolver JsonConverter and directly control the (de-)serialization.

编辑:我创建了一个小例子更具体

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

这篇关于如何更改为数字反序列化的默认类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆