当我向服务(我不拥有)发送请求时,它可能会以请求的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子句…以防万一。
有了Json.NET您,您可以针对架构验证json:
Json.NET
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方法中使用它。
public static T TryParseJson<T>(this string json, string schema) where T : new() { JsonSchema parsedSchema = JsonSchema.Parse(schema); JObject jObject = JObject.Parse(json); return jObject.IsValid(parsedSchema) ? JsonConvert.DeserializeObject<T>(json) : default(T); }
然后做:
var myType = myJsonString.TryParseJson<AwsomeType>(schema);
请注意,架构验证不再是Newtonsoft.Json主程序包的一部分,您需要添加Newtonsoft.Json.Schema程序包。
如评论中所述,“ JSONSchema”具有定价模型,这意味着 它不是免费的 。您可以在这里找到所有信息