如何更改数字反序列化的默认类型?

2024-05-13

我正在将一些属性反序列化为Dictionary<string, object>.

当我反序列化一些 json 时,它会填充Dictionary with Int64对象而不是Int32。我想要它选择Int32作为默认值,我知道我可能有在转换时会溢出的 javascript 数字。在这种情况下抛出异常是完全可以接受的。

有什么办法可以实现这一点吗?我希望有一些不错的属性或方便的接口可以实现并添加到JsonSerializer。我担心我必须深入 Json.NET 的深处。

基本上我希望有某种方法来控制对象的已知类型,以便我可以获得Int32的而不是Int64 and DateTimes代替Strings.


据我所知,没有内置的方法可以做到这一点。

有一个issue https://web.archive.org/web/20160606030722/http://json.codeplex.com/workitem/20832关于这个主题,但它已经关闭了。 作者对此问题的一些评论:

Json.NET 默认将整数值读取为 Int64,因为无法知道该值应该是 Int32 还是 Int64,而且 Int64 不太可能溢出。对于类型化属性,反序列化器知道将 Int64 转换为 Int32,但由于您的属性是非类型化的,因​​此您将获得 Int64。 [...] 这就是 Json.NET 的工作方式。

最简单的解决方案当然是将类型更改为Dictionary<string, int>,但我想你不仅在阅读数字,因此还被困在object.

Another option would be to either use Serialization Callbacks http://james.newtonking.com/projects/json/help/SerializationCallbacks.html and manually convert those Int64s to Int32 or create your own Contract Resolver http://james.newtonking.com/projects/json/help/ JsonConverter http://james.newtonking.com/projects/json/help/ and directly control the (de-)serialization.


Edit:我创建了一个小例子来更具体。

这是一个非常基本的转换器,仅适用于您的特定字典:

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

您可以使用属性来通过转换器来装饰成员,或者将其作为参数传递 http://james.newtonking.com/projects/json/help/到(反)序列化方法。这是我使用属性的示例:

    [JsonObject]
public class MyObject {
    [JsonConverter(typeof(Int32Converter))]
    public Dictionary<string, object> Properties { get; set; }
}

这是我用来测试实现的代码:

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

如果没有转换器,结果将是:

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改数字反序列化的默认类型? 的相关文章

随机推荐

  • 打字稿交集类型和函数签名不会引发预期错误

    我声明了以下类型 type ExampleA a string type ExampleB b number type ExampleC c boolean type Examples ExampleA ExampleB ExampleC
  • 如何使

    我有一个列表 用作选项卡列表 div ul class TabControl li a href search Funds Funds 60 a li li a href search Companies Companies 4 a li
  • jQuery自动完成插件-自定义突出显示功能

    我的每个项目的自动完成结果如下所示 h3 Celebrity Sweepstakes h3 p 0 episodes p 但我只想突出显示 H3 内的标题 请参阅下面的 突出显示 功能 我不知道如何更改原始正则表达式以仅替换标题内的内容 s
  • 错误“达到 inotify 监视的用户限制”。 ExtReact 构建

    我安装了 ExtReact 并附有示例 当我跑步时 npm start 我收到错误 ERROR in extjs reactor webpack plugin Error ERR BUILD FAILED ERR com sencha ex
  • SQL Server 到 er 模型

    是否有程序可以将 SQL Server 数据库图表转换为 er 模型 或者从 SQL Server 服务器创建数据库的 er 模型 在 SQL Server 中 Management Studio 中的每个数据库都有 数据库图 功能 您可以
  • 将两个 Int 值相除以获得 Float 的正确方法是什么?

    我想分两份IntHaskell 中的值并获得结果Float 我尝试这样做 foo Int gt Int gt Float foo a b fromRational a b 但 GHC 版本 6 12 1 告诉我 无法将预期类型 Intege
  • 无法打开 TypeScript 项目的扩展开发主机

    我正在尝试阅读第一个 VS Code 扩展教程 但无法打开扩展开发主机 按 F5 没有任何反应 单击调试侧栏中的开始按钮似乎也没有执行任何操作 我已经使用生成了我的项目yo code并选择了 TypeScript 选项 我尝试过选择 Jav
  • 如何读取一次流数据集并输出到多个接收器?

    我有 Spark 结构化流作业 它从 S3 读取数据 转换数据 然后将其存储到一个 S3 接收器和一个 Elasticsearch 接收器 目前 我正在做readStream一次然后writeStream format start 两次 这
  • 带有 ListTiles 和按钮行的 Flutter 下拉菜单

    我正在尝试构建一个自定义下拉菜单 如下所示 我已经成功地实现了ListTiles and Row of Buttons没有下拉菜单 但我不确定如何将所有内容嵌套在下拉菜单类中 这是我到目前为止所得到的 class HomePage exte
  • Android Studio:如果设置项目的背景颜色,ListView OnClick 动画将不起作用

    在我的项目中 我在 ListView 内设置了项目 由插入 ConstraintLayout 中的多个元素组成 的背景颜色 但如果背景颜色不是至少一点透明 则单击和长按的默认动画会消失 事实上 随着透明度的降低 点击元素的效果越来越不明显
  • 验证 ActionCable 连接

    我发现了一个很棒的 ActionCable gem 它是 SPA 的一个很好的解决方案 我只想发送html css and js资产 所有其他连接将通过ActionCable 交换字符串或者整数并不难 但是如何通过ActionCable登录
  • 单击一次文件丢失

    将 Clickonce 与 VS 2010 和 NET Framework Client profile 3 5 一起使用 我有几个文件夹 其中包含运行时所需的应用程序级 XML 和 或文本文件 这些文件夹位于要使用它们的同一项目中 这些文
  • 在 C# 中反序列化 JSON 日期时出现问题 - 添加 2 小时

    将 JSON 日期反序列化为 C DateTime 时 我们遇到了一个棘手的问题 代码是 JavaScriptSerializer serializer new JavaScriptSerializer jsonTrechos jsonTr
  • 参考接口创建对象

    引用变量可以声明为类类型或接口类型 如果变量声明为接口类型 则它可以引用实现该接口的任何类的任何对象 根据上面的说法我做了一个理解上的代码 正如上面所说声明为接口类型 它可以引用实现该接口的任何类的任何对象 但在我的代码中显示display
  • fputc() 之后 c fgetc() 中的文件处理问题

    我有一个带有文件名的文本文件in txt 其中包含以下内容 1111 1100 0000 我正在尝试使用以下程序更改此文件的内容 include
  • 批量设置命令的输出和错误以分隔变量

    在Windows 7批处理 cmd exe命令行 中 我试图将命令的标准输出 stdout 和标准错误 stderr 重定向到单独的变量 因此第一个变量设置为输出 第二个变量设置为输出 变量设置为错误 如果有 而不使用任何临时文件 我已经尝
  • PyQt:如何设置组合框项目可检查?

    为了将 GUI 小部件数量保持在最低限度 我需要找到一种方法来为用户提供下拉菜单项的选择 这些菜单项可用于过滤掉 listWidget 项中显示的内容 假设 listWidget 列出了 5 个不同类别的项目 Cat A Cat B Cat
  • 递归链接 Promise

    我正在开发一个简单的 Windows 8 应用程序 我需要在其中从网站获取一组数据 我正在使用 WinJS xhr 来检索此数据 它返回一个 Promise 然后 我将回调传递到此 Promise 的 then 方法中 该方法为我的回调提供
  • Openxlsx 多次验证损坏输出文件

    我正在尝试添加多个验证并将公式添加到 Excel 文件 这是我使用的代码 library openxlsx fileTemplate lt New01 xlsx wbTemplate lt loadWorkbook fileTemplate
  • 如何更改数字反序列化的默认类型?

    我正在将一些属性反序列化为Dictionary