反序列化JSON在"的TryParse"方法 [英] Deserialize json in a "TryParse" way

查看:410
本文介绍了反序列化JSON在"的TryParse"方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我请求发送到一个服务(即我没有自己)可能既响应与请求JSON数据,无论是与一个JSON的错误,看起来像这样:

When I send a request to a service (that I do not own) it may responds either with the json data requested, either with a json error that looks like that :

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

在这两种情况下, HTTP响应code 200确定。 所以,我不能依赖它,我要反序列化的反应来检查它是否是一个错误或没有。 所以,我有东西,看起来像这样:

In these two cases, HTTP response code is 200 OK. So, I cannot rely on it, i have to deserialize the response to check whether it is an error or not. So I have something that looks like that :

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.
            // It may be a successful JSON response : do nothing.
        }
    }

    error = null;
    return false;
}

在这里,我有一个空的catch子句可能在标准执行路径,这是一个不好的气味......好了,多了难闻的气​​味:太臭

Here, I have an empty catch clause that may be in the standard execution path, which is a bad smell... Well, more than a bad smell : it stinks.

你知道一个更好的方式为的TryParse,以便响应避免在标准的执行路​​径的catch

Do you know a better way to "TryParse" the response in order to avoid a catch in the standard execution path ?

由于尤瓦Itzchakov 的答案,我提高了我的方法,这样的:

Thanks to Yuval Itzchakov's answer I improved my method like that :

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子句...以防万一。

I kept the catch clause... just in case.

推荐答案

通过 Json.NET 可以验证对架构的JSON:

With Json.NET you can validate your json against a schema:

 string schemaJson = @"{
 'status': {'type': 'string'},
 'error': {'type': 'string'},
 'code': {'type': 'string'}
}";

JsonSchema schema = JsonSchema.Parse(schemaJson);

JObject jobj = JObject.Parse(yourJsonHere);
if (jobj.IsValid(schema))
{
    // Do stuff
}

,然后使用一个的TryParse方法内

And then use that inside a TryParse method

public static T? TryParseJson<T>(this string json, string schema) where T : new()
{
  JsonSchema parsedSchema = JsonSchema.Parse(schema);
  JObject jObject = JObject.Parse(json);

  if (!jObject.IsValid(parsedSchema))
  {
     return default(T);
  }

  return (T)JsonConvert.DeserializeObject(json);
} 

然后执行:

var myType = myJsonString.TryParseJson<AwsomeType>(schema);

这篇关于反序列化JSON在&QUOT;的TryParse&QUOT;方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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