gpt4 book ai didi

c# - 以 "TryParse"的方式反序列化 json

转载 作者:IT老高 更新时间:2023-10-28 12:44:55 32 4
gpt4 key购买 nike

当我向服务(我不拥有该服务)发送请求时,它可能会以请求的 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 子句,它可能位于标准执行路径中,这是一种难闻的气味……嗯,不仅仅是难闻的气味:它很臭。

您知道“TryParse”响应以避免在标准执行路径中捕获的更好方法吗?

[编辑]

感谢 Yuval Itzchakov的回答我改进了我的方法:

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 调用,因此它们实际上被忽略了。

这是他的扩展方法的“免费”版本,其中还包括缺少成员标志。避免捕获的关键是将设置对象的 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…
}

关于c# - 以 "TryParse"的方式反序列化 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23906220/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com