以“TryParse”方式反序列化 json

2023-11-22

当我向某个服务(不属于我)发送请求时,它可能会响应所请求的 JSON 数据,或者响应如下所示的错误:

{
    "error": {
        "status": "error message",
        "code": "999"
    }
}

在这两种情况下,HTTP 响应代码都是 200 OK,因此我无法使用它来确定是否存在错误 - 我必须反序列化响应才能检查。 所以我有一些看起来像这样的东西:

bool TryParseResponseToError(string jsonResponse, out Error error)
{
    // Check expected error keywords presence
    // before try clause to avoid catch performance drawbacks
    if (jsonResponse.Contains("error") &&
        jsonResponse.Contains("status") &&
        jsonResponse.Contains("code"))
    {
        try
        {
            error = new JsonSerializer<Error>().DeserializeFromString(jsonResponse);
            return true;
        }
        catch
        {
            // The JSON response seemed to be an error, but failed to deserialize.
            // Or, it may be a successful JSON response: do nothing.
        }
    }

    error = null;
    return false;
}

在这里,我有一个空的 catch 子句,它可能位于标准执行路径中,这是一种难闻的气味......好吧,不仅仅是一种难闻的气味:它很臭。

你知道更好的方法吗“尝试解析”响应以便避免捕获在标准执行路径中?

[EDIT]

谢谢尤瓦尔·伊茨恰科夫的回答我改进了我的方法:

bool TryParseResponse(string jsonResponse, out Error error)
{
    // Check expected error keywords presence :
    if (!jsonResponse.Contains("error") ||
        !jsonResponse.Contains("status") ||
        !jsonResponse.Contains("code"))
    {
        error = null;
        return false;
    }

    // Check json schema :
    const string errorJsonSchema =
        @"{
              'type': 'object',
              'properties': {
                  'error': {'type':'object'},
                  'status': {'type': 'string'},
                  'code': {'type': 'string'}
              },
              'additionalProperties': false
          }";
    JsonSchema schema = JsonSchema.Parse(errorJsonSchema);
    JObject jsonObject = JObject.Parse(jsonResponse);
    if (!jsonObject.IsValid(schema))
    {
        error = null;
        return false;
    }

    // Try to deserialize :
    try
    {
        error = new JsonSerializer<Error>.DeserializeFromString(jsonResponse);
        return true;
    }
    catch
    {
        // The JSON response seemed to be an error, but failed to deserialize.
        // This case should not occur...
        error = null;
        return false;
    }
}

我保留了 catch 条款...以防万一。


@Victor LG 使用 Newtonsoft 的答案很接近,但它在技术上并没有像原始海报所要求的那样避免捕获。它只是将其移动到其他地方。此外,虽然它创建了一个设置实例来捕获丢失的成员,但这些设置不会传递给 DeserializeObject 调用,因此它们实际上会被忽略。

这是他的扩展方法的“catch free”版本,其中还包括缺少成员标志。避免捕获的关键是设置Error设置对象的属性为 lambda,然后设置一个标志来指示失败并清除错误,这样就不会导致异常。

 public static bool TryParseJson<T>(this string @this, out T result)
 {
    bool success = true;
    var settings = new JsonSerializerSettings
    {
        Error = (sender, args) => { success = false; args.ErrorContext.Handled = true; },
        MissingMemberHandling = MissingMemberHandling.Error
    };
    result = JsonConvert.DeserializeObject<T>(@this, settings);
    return success;
}

这是一个使用它的示例:

if(value.TryParseJson(out MyType result))
{ 
    // Do something with result…
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以“TryParse”方式反序列化 json 的相关文章

  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • EF4 Code First - 如何正确映射跨多个表拆分实体

    我正在使用 EF4 CTP5 尝试保留一个 POCO 对象 该对象分为两个表 链接是 ContactID 当我保存联系人时 我希望将核心联系人信息保存在一个表 联系人 中 并将拥有该联系人的用户的链接保存在另一个表 UserToContac
  • MongoException:不允许使用零长度键,您是否使用带双引号的 $ ?

    我正在使用 symfony2 和 mongodb 直到今天 一切正常 但是我创建一个新文档 突然出现此错误 MongoException 不允许使用零长度键 您是否使用带双引号的 dm this gt get doctrine odm mo
  • GitLab 统计问题总数

    我想使用 api 统计我的 gitlab 项目上的所有问题 下面是我正在使用的命令 curl header PRIVATE TOKEN xxxxxxx https gitlab myapp com api v4 groups xx issu
  • 在 Typescript 项目中导入 Matter-js

    我找到了这个文件 https www npmjs com package types matter js 我执行这一行 npm install save types matter js 在根 ts 文件中我收到错误消息 Matter 指的是
  • 如何在 Jasper Report 中组织框架,使它们完美浮动?

    在 Jasper 报告中 我有 4 个框架 下图 它们设置了一些属性 如同一个图像中所示 现在 想法是给定某些参数showBlue and showRed框架BLUE and RED分别显示或隐藏 后续帧 浮动 在前一帧之后 考虑以下顺序
  • unordered_set 非常量迭代器

    出于测试目的 我创建了一些 unordered set 并尝试迭代该集合 该集合拥有自己的类 class Student private int matrNr string name public Student const int mat
  • 使用 React、Redux 和 Axios 处理异步请求?

    我是 React JS 和 Redux 的新手 这让我难以上手 我正在尝试使用 Axios 发出 POST 请求 但无法发出请求 可能是我在容器文件中丢失了一些东西 下面是代码 查看plnkr Update 提交后我收到 redux for
  • 将列表与公共元素合并

    我有一个清单 1 1 7 2 1 10 11 12 211 446 469 3 1 10 11 12 13 4 1 11 12 13 215 5 1 15 16 6 1 15 17 216 225 我想合并具有公共元素的列表切片 并索引已合
  • 红宝石浮点精度

    据我了解 Ruby 1 9 2 浮点数的精度为 15 位十进制数字 因此 我期望舍入浮动x精确到小数点后 15 位等于x 对于此计算 情况并非如此 x 0 33 10 x x round 15 gt false 顺便说一下 四舍五入到 16
  • 在 iOS7 GM 中收到 SSL 错误 - “AddTrust 外部 CA 根”不受信任?

    我的 NSURLConnection 类中突然收到来自 iOS7 GM 的 SSL 错误 我无法访问我的任何 API 或 webView 页面 这是一个严重的紧急情况 有人可以帮我吗 错误如下 NSURLConnection CFURLCo
  • 使用事件侦听器克隆引导元素

    我正在尝试克隆一个具有引导程序提供的数据切换行为的引导程序元素 HTML div class container div
  • 我需要帮助使用 MAT 查找内存泄漏

    我正在使用 MAT 来比较两个堆转储 我每天都会进行一次堆转储 它每天都会增加大约 200 兆 我认为泄漏与 java util zip 有关 因为该表显示的内容 也因为我们最近添加了一个新进程来压缩和解压缩大量文件 见图 此时我打开支配器
  • iPhone 上的 HTTP 直播流媒体服务器

    我正在尝试在 iPhone 上运行 HTTP 实时流媒体服务器 该服务器从摄像头捕获视频流并将其提供给 HTML5 客户端 支持 HTTP 实时流媒体 到目前为止 我已经完成了以下工作 iOS 上的 HTTP Live 流媒体服务器 用 N
  • Ext 4.1.1:添加新记录到Store

    我想在商店初始化后添加记录 I tried 加载数据 加载原始数据 add 但似乎没有任何作用 这是我的jsfiddle http jsfiddle net charlesbourasseau zVvLc 有任何想法吗 你需要设置query
  • novalidate 并出现错误 ora-02299

    有人可以帮我解决这个问题吗 id Name 1 aaa 2 bbb 3 aaa gt alter table arc add CONSTRAINT uk arc UNIQUE NAME novalidate error ora 02299
  • 控制 HTML5 视频中的开始位置和播放时长

    我们有一个视频 长 13 分钟 我们希望使用 HTML5 对其进行控制 我们希望能够让用户控制和选择他们想要播放的视频部分 优选地 该控制将通过2个输入字段进行 他们将在第一个框中输入开始时间 以秒为单位 并在第二个框中输入播放持续时间 以
  • Haxe 在 PHP 环境中部署的 Web“框架”?

    最近我一直在看Haxe 构建要部署到运行 PHP 的 Apache 的应用程序 好吧 虽然它看起来可能适合我的需求 部署到 PHP 但不使用糟糕的语言 但我还没有发现任何东西可以使实际应用程序开发比构建传统的非 MVC PHP 应用程序更容
  • Angular 构建:无法读取未定义的属性“split”

    刚刚从 ng8 升级到 ng11 当我运行 ngserve 时它工作正常 但是当我运行 build 进行生产时我收到以下错误 生成 ES5 包以进行差异加载 发生未处理的异常 C P src app 9 es2015 dce42a686e4
  • CUDA 10 不支持 7 之后的 Gcc 版本 - Arch Linux 中的 Qt 错误

    我正在运行 Arch Linux 并尝试在 Qt 中构建一个项目 但是 Qt 出现以下错误 opt cuda include crt host config h 129 错误 error 不支持的 GNU 版本 不支持 7 之后的 gcc
  • 以“TryParse”方式反序列化 json

    当我向某个服务 不属于我 发送请求时 它可能会响应所请求的 JSON 数据 或者响应如下所示的错误 error status error message code 999 在这两种情况下 HTTP 响应代码都是 200 OK 因此我无法使用