2016-04-07 3 views
1

Я пишу инструмент на C#, который делает несколько вызовов ServiceNow через таблицу REST API. Я использую RESTsharp для вызова REST, а JSON.net - для десериализации результатов. Это очень хорошо работает для запросов, которые не возвращают ошибку.Сложность с ошибкой синтаксического анализа JSON из ServiceNow REST API

 try 
     { 

      DataSet dataset = JsonConvert.DeserializeObject<DataSet>(response.Content); 
      results = dataset.Tables["result"]; 

      return (results); 
     } 

     catch (Exception e) 
     { 
     .... 
     } 

Однако, когда возвращается ошибка, например, результатов не найдено, я получаю неожиданный маркер исключение при попытке разобрать ошибки. «Неожиданный токен JSON при чтении DataTable Ожидаемого StartArray, получили StartObject»

Точной JS вернулась ниже:

{ 
    "error": { 
    "message": "No Record found" 
    "detail": "Records matching query not found. Check query parameter or offset parameter" 
    } 
    "status": "failure" 
} 

Я прочитал несколько подобных вопросы, и попытался сделать свой собственный класс, но я m не совсем уверен, как именно я должен это реализовать.

+1

Вы получаете коды статуса HTTP возвращены иначе, когда вы получите сообщение об ошибке сообщение? Если это так, вы можете проверить код состояния ответа и десериализовать свой ответ по-разному в зависимости от кода состояния. Вы можете создать простой класс для сопоставления с объектом ошибки - просто соответствовать свойствам возвращенного json. –

+0

Да, я надеялся, что он вернет 404 или что-то в этом роде, но это всего лишь 200 ОК с текстом выше. – Noobixide

+0

Я не на 100% удобен с этим подходом, но если они всегда возвращают 200, вы всегда можете попробовать и десериализовать свой собственный объект «error» в вашем блоке catch. В частности, поймайте 'UnexpectedTokenException' и попробуйте десериализовать объект ошибки. Сохраните общий 'catch (Exception e)' там также. –

ответ

1

Учитывая, что веб-служба не должным образом возвращается состояние ошибки, можно разобрать на промежуточную JToken затем проверить, если ответ выглядит как ошибка или нет:

var token = JToken.Parse(response.Content); 
if (token.Type == JTokenType.Object && ((JToken)"failure").Equals(token["status"])) 
{ 
    // Handle error explicitly 
    return null; 
} 

var dataset = token.ToObject<DataSet>(); 
var results = dataset.Tables["result"]; 
return results; 

В качестве альтернативы вы можете поймать JsonException и проверьте наличие явной ошибки. Я не рекомендую этот подход, поскольку это зависит от того, что JSON для ошибки не может быть случайно десериализованными как JSON для DataSet:

try 
{ 
    try 
    { 
     var dataset = JsonConvert.DeserializeObject<DataSet>(response.Content); 
     var results = dataset.Tables["result"]; 

     return results; 
    } 
    catch (JsonException) 
    { 
     var token = JToken.Parse(response.Content); 
     if (token.Type == JTokenType.Object && ((JToken)"failure").Equals(token["status"])) 
     { 
      // Handle error explicitly 
      return null; 
     } 
     // OK, it's not an explicit error. rethrow 
     throw; 
    } 
} 
catch (Exception ex) 
{ 
    // Generic error in the code somewhere. 
    Debug.WriteLine(ex); 
    // ... Other error handling as required 
} 
+0

@Noobixide - Я только что закончил этот ответ и прочитал ваш комментарий, что вы получаете должное возвращение 404 в конце концов. Вам все еще нужен ответ? – dbc