使用 JsonReader 而不是 JsonSerializer 时自定义 JsonConverter 不起作用

2023-12-09

我有课Foo和它的FooConverter定义如下:

[JsonConverter(typeof(FooConverter))]
public class Foo
{
    public string Something { get; set; }
}

public class FooConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(((Foo)value).Something);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var str = reader.ReadAsString();
        if (str == null)
        {
            throw new JsonSerializationException();
        }    
        // return new Foo {Something = serializer.Deserialize<string>(reader)};
        return new Foo {Something = str};
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Foo);
    }
}

序列化工作正常。但反序列化时:

var foo = JsonConvert.DeserializeObject<Foo>("\"something\"");

它抛出JsonSerializationException因为reader.ReadAsString一片空白。
但我不明白为什么一定要这样null... reader.ReadAsString如果我像这样手动执行此操作,则可以完美找到:

var reader = new JsonTextReader(new StringReader("\"something\""));
var str = reader.ReadAsString(); // str is now `something` NOT null

虽然我可以修复FooConverter通过使用serializer.Deserialize<string>(reader) in ReadJson,我还是想明白为什么reader.ReadAsString失败了FooConverter.ReadJson.


你的问题是,根据文档, JsonReader.ReadAsString():

读到next来自源的 JSON 令牌作为字符串。

然而,当JsonConverter.ReadJson()被调用时,读取器已经定位到与正在反序列化的对象相对应的第一个 JSON 标记。因此,通过调用ReadAsString()您丢弃该值并尝试读取流中的下一个标记 - 但没有,因此您抛出异常。

此外,在年底ReadJson()您的代码必须将读取器定位到与正在转换的对象对应的最后一个 JSON 标记。因此,在 JSON 只是一个原语的情况下,读者根本不应该先进。

保证读者始终正确定位的简单方法ReadJson()是打电话JToken.Load()。这始终使读取器位于已加载令牌的末尾。之后,您可以检查加载的内容是否符合预期。例如,如果 JSON 中有一个需要字符串的对象,而不是让读取器处于错误的位置,那么转换器应该抛出异常,而不是让读取器处于错误的位置。

StringIdConverter from Json.Net:将属性序列化/反序列化为值,而不是对象举了一个例子。您可以按如下方式修改它:

public class FooConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        if (!(token is JValue))
            throw new JsonSerializationException("Token was not a primitive");
        return new Foo { Something = (string)token };
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 JsonReader 而不是 JsonSerializer 时自定义 JsonConverter 不起作用 的相关文章

  • Automapper、Mapper 未初始化。使用正确的配置调用初始化

    当我尝试将数据提交到数据库时 出现以下错误 Success false Error true ErrorType 2 Message System InvalidOperationException Mapper 未初始化 使用适当的配置调
  • 在 XML 中,带问号的节点叫什么?在 C# 中如何添加它们?

    以下是在 InfoPath 中创建的 XML 文件的示例
  • Qt 和 Sqlite 示例

    我正在寻找一些使用 Qt 的示例代码 它是带有 Sqlite 驱动程序的 SQL 模块 我需要示例的主要原因是我之前有 Qt 数据库接口的经验 并且 Sqlite 在字段类型方面有一些奇怪的行为 类型是按字段存储的 而不是按列存储的 The
  • C++ STL 映射,std::pair 作为键

    这就是我通过地图定义的方式 std map
  • MVVM:来自 FileOpenPicker 的图像绑定源

    我将 OnActivated 添加到 app xaml cs 中 它可以正常工作 protected async override void OnActivated IActivatedEventArgs args var continua
  • 处理器关联组 C#

    我使用的是 72 核的 Windows Server 2016 我看到有两组处理器 我的 net 应用程序将使用一个或其他组 我需要能够强制我的应用程序使用我选择的组 我看到下面的代码示例 但我无法使其工作 我可能传递了错误的变量 我希望应
  • 二叉树和快速排序?

    我有一个家庭作业 内容如下 别生气 担心 我是not请你帮我做作业 编写一个程序 通过使用二分查找的快速排序方法对一组数字进行排序 树 推荐的实现是使用递归算法 这是什么意思 到目前为止 这是我的解释 正如我在下面解释的那样 我认为两者都有
  • 图片框、双击和单击事件

    我有一个奇怪的问题 我有一个图片框双击事件以及单击事件 问题是即使我双击该控件 也会引发单击事件 如果我禁用单击事件 则双击事件正在工作 这个问题已经在这里讨论过 https stackoverflow com questions 1830
  • 在编译输出中添加程序集绑定 (app.config)

    如果我编译应用程序 则会在输出中自动添加程序集绑定 具体的程序集绑定不在app config在 Visual Studio 中但在创建的应用程序配置中 有什么办法可以检查为什么会自动添加程序集绑定吗 选项AutoGenerateBindin
  • 如何在 C++11 中返回类成员向量

    我读了几篇关于如何从方法返回向量的文章 其中包括 c11 右值和移动语义混淆返回语句 https stackoverflow com questions 4986673 c11 rvalues and move semantics conf
  • 如何在C++中列出Python模块的所有函数名称?

    我有一个 C 程序 我想导入一个 Python 模块并列出该模块中的所有函数名称 我该怎么做 我使用以下代码从模块中获取字典 PyDictObject pDict PyDictObject PyModule GetDict pModule
  • 模板类中模板方法专门化的 clang 自动返回类型错误?

    试图理解另一个问题 https stackoverflow com questions 38054055 clang fails to compile template function with auto return type insi
  • 结构大小与 typedef 版本不同?

    我的代码中有以下结构声明和 typedef struct blockHeaderStruct bool allocated unsigned int length typedef struct blockHeaderStruct block
  • 用 std::generate_n 填充 std::map

    我想填写一个std map using std generate n但无法让它发挥作用 我尝试过的是这样的事情 unsigned number of pairs 5 std map
  • 在 C 中运行 setuid 程序的正确方法

    我有一个权限为4750的进程 我的Linux系统中存在两个用户 root 用户和 appz 用户 该进程继承以 appz 用户身份运行的进程管理器的权限 我有两个基本惯例 void do root void int status statu
  • 使用属性和性能

    我正在优化我的代码 我注意到使用属性 甚至自动属性 对执行时间有深远的影响 请参阅下面的示例 Test public void GetterVsField PropertyTest propertyTest new PropertyTest
  • 对 Action 方法的两个并行 ajax 请求排队,为什么?

    我正在使用 ASP NET MVC 开发一个视频网站 我希望在我的应用程序中拥有的一项功能是转码视频 但由于转码过程可能非常耗时 我想向客户端用户展示该过程的进度 因此 我的架构是使用一个控制器操作来处理整个转码过程 并将其进度写入存储在服
  • 在for循环中声明和初始化变量

    可以简单写一下吗 for int i 0 代替 int i for i 0 在 C 或 C 中 并且会变量i只能在循环内部访问 它在 C 中有效 它在 C 的原始版本中是不合法的 但在 C99 中被采用为 C 的一部分 当时一些 C 功能被
  • C# 使用 .Equals() 比较两个 double

    我使用 ReShaper 当我用 比较两个双精度值时 它建议我应该使用 Math 具有公差的 ABS 方法 看 https www jetbrains com help resharper 2016 2 CompareOfFloatsByE
  • 在派生类中访问基类变量

    class Program static void Main string args baseClass obj new baseClass obj intF 5 obj intS 4 child obj1 new child Consol

随机推荐

  • OAuth2 - 检索 TOKEN 时 OPTIONS 请求的状态 401

    我们的堆栈使用 Backbone 作为客户端应用程序 使用 Spring Boot 作为 RESTful API 我们正在尝试使用 OAuth2 进行基本身份验证 并由用户提供用户名和密码 我们使用 Spring Security 进行身份
  • 在 ES6 中正确扩展数组/代理?

    目前正在尝试制作数组 对象的自定义实现 我想最终会非常相似 并且偶然发现了一个让我发疯的问题 正如您所看到的 b 只是一个 array 的实例 即使它是从自定义类 CachedArray 创建的 因此我的自定义函数 testPush 未定义
  • Rails SELECT 40001 SQL_NO_CACHE 从未知位置触发

    在 MySQL 数据库服务器中 我们有名为test 该架构具有名为users 桌子usersRails 应用程序未在任何地方使用 唯一的入口处users发现位于 schema rb 中 The users表存储了一些数据 并且数据由在其他服
  • Fluent NHibernate 使用 FluentMappings 忽略 ClassMap 内的属性

    我在我的项目中使用 NHibernate 3 1 和 Fluent NHibernate 作为 ORM 我需要有一个被 Fluent NHibernate 忽略的 POCO 属性 起初 我的帖子可能看起来与这个问题 但事实并非如此 我的复杂
  • arima.sim() 函数具有变化:样本大小、phi 值和 sd 值

    我想模拟ARIMA 1 1 0 随变化 样本量 phi值 标准偏差值 我很佩服下面的吼叫r代码只是模拟一个ARIMA 1 1 0 我想遵循格式来模拟许多ARIMA 1 1 0 随着变化的样本量 phi值 and 标准偏差值 wn lt rn
  • 无法执行不同的投影查询

    我有一个简单的小 观察 课 from google appengine ext import ndb class Observation ndb Model remote id ndb StringProperty dimension id
  • 在 MVC3 中使用 WebApi

    使用 WebApi 在 MVC 客户端中使用服务的最佳方式是什么 如果响应返回为
  • PHP数据库连接实践

    我有一个连接到多个数据库 Oracle MySQL 和 MSSQL 的脚本 每次脚本运行时可能不会使用每个数据库连接 但所有数据库连接都可以在单个脚本执行中使用 我的问题是 即使所有连接可能都没有被使用 最好在脚本开始时连接到所有数据库一次
  • 基于范围的 for 如何适用于普通数组?

    在 C 11 中 您可以使用基于范围的for 其作用为foreach其他语言的 它甚至适用于普通的 C 数组 int numbers 1 2 3 4 5 for int n numbers n 2 它如何知道何时停止 它是否仅适用于已在同一
  • 为什么同样的方法在 Swift 的数组扩展中会失败?

    当我尝试打电话时 我的行为很奇怪sort 从数组扩展中 例如此方法 func test let a 1 2 3 sort a x y in x lt y 可以单独工作 但在内部时会失败Array扩大 extension Array func
  • 从字节数组中创建新的 FileStream

    我正在尝试从字节数组创建一个新的 FileStream 对象 我确信这根本没有意义 所以我将在下面尝试更详细地解释 我正在完成的任务 1 读取之前的源文件压缩的2 使用GZipStream解压数据 3 将解压后的数据复制到字节数组中 我想改
  • Android 设备重启后广播接收器不工作

    我已经检查了所有相关问题 但没有找到解决此问题的方法 所以这对我来说绝对是一个新问题 我拥有的 我有一个 Android 应用程序 它在其清单中注册了一些广播接收器 这就是我的清单的样子
  • JavaFX:父级及其子级的鼠标单击事件

    我有一张卡片 由页眉 正文和页脚组成 可以包含更多节点 如标签 文本字段等 我需要抓住on mouse clicked单击发生时的任何时间事件卡内 无论它是卡本身还是它的子卡之一 现在 如果我单击文本字段 则不会触发事件 private S
  • 在发布的 Android 应用程序中完全禁用 LogCat 输出?

    关闭my own在将应用程序发布到市场之前 应用程序的 LogCat 输出非常简单 我还知道如何通过标签和 或 id 有选择地过滤 LogCat 消息 以方便我自己的调试 但现在我对一些可能更困难 也许不可能 的事情感兴趣 禁用所有 Log
  • 如何在zend框架中添加新类并自动加载

    我是 Zend 框架的新手 第一次使用它 我正在寻找可以在很短的时间内阅读的简单基础教程 如果我想在 Zend 库中添加新类 我也坚持这样做 当我制作任何新控制器时 它也应该自动加载 如果您有意见 请提出您的意见 Regards 这在一开始
  • 在基本身份验证 URL 中转义用户名字符

    使用http基本身份验证时 可以在URL中传递用户名 例如 http email protected path 但现在假设用户名是电子邮件地址 例如 电子邮件受保护 这样做显然是不明确的 http email protected foo c
  • LESS:您可以将 CSS 选择器与媒体查询分组吗?

    我真的很高兴发现您可以创建一个媒体查询变量 您可以轻松地重用该变量并使您的代码更具可读性 tablet min width 768px and max width 980px media tablet 我想知道是否可以将媒体查询与选择器分组
  • IBM Worklight - 如何更改默认的“Worklight 设置”字符串?

    有没有办法更改 Android 选项菜单中 Worklight 提供的默认 Work Light 设置 字符串 Update 稍微纠正一下答案 Yes 打开您的App is 位于yourProject apps yourApp common
  • 在eclipse中使用java库

    我对 eclipse 有点陌生 想要使用以下库 以便我可以使用它们实现的对象 HttpClient 和 Java csv 我如何导入这些库以便我可以用它们编写一些java http hc apache org downloads cgi h
  • 使用 JsonReader 而不是 JsonSerializer 时自定义 JsonConverter 不起作用

    我有课Foo和它的FooConverter定义如下 JsonConverter typeof FooConverter public class Foo public string Something get set public clas