У меня есть сырая строка. Я просто хочу проверить, является ли строка допустимым JSON или нет. Я использую JSON.NET.
У меня есть сырая строка. Я просто хочу проверить, является ли строка допустимым JSON или нет. Я использую JSON.NET.
Ответы:
Через код:
Лучше всего использовать синтаксический анализ внутри a try-catchи перехватить исключение в случае неудачного анализа. (Я не знаю ни одного TryParseметода) .
(Используя JSON.Net)
Простейшим способом было бы Parseиспользовать строку JToken.Parse, а также проверить, начинается ли строка с {или [и заканчивается ли }или ]соответственно (добавлено из этого ответа ) :
private static bool IsValidJson(string strInput)
{
if (string.IsNullOrWhiteSpace(stringValue)) { return false;}
strInput = strInput.Trim();
if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || //For object
(strInput.StartsWith("[") && strInput.EndsWith("]"))) //For array
{
try
{
var obj = JToken.Parse(strInput);
return true;
}
catch (JsonReaderException jex)
{
//Exception in parsing json
Console.WriteLine(jex.Message);
return false;
}
catch (Exception ex) //some other exception
{
Console.WriteLine(ex.ToString());
return false;
}
}
else
{
return false;
}
}
Причина добавления проверок для {и [т. Д. Была основана на том факте, что они JToken.Parseбудут анализировать такие значения, как "1234"или "'a string'"как действительный токен. Другим вариантом может быть использование обоих JObject.Parseи JArray.Parseпри разборе, и посмотреть, удастся ли кому-нибудь из них, но я считаю, что проверка {}и []должна быть проще. (Спасибо @RhinoDevel за указание на это)
Без JSON.Net
Вы можете использовать пространство имен .Net framework 4.5 System.Json , например:
string jsonString = "someString";
try
{
var tmpObj = JsonValue.Parse(jsonString);
}
catch (FormatException fex)
{
//Invalid json format
Console.WriteLine(fex);
}
catch (Exception ex) //some other exception
{
Console.WriteLine(ex.ToString());
}
(Но вы должны установить System.Jsonчерез менеджер пакетов Nuget с помощью команды: PM> Install-Package System.Json -Version 4.0.20126.16343на консоли диспетчера пакетов) (взято отсюда )
Не кодовый способ:
Обычно, когда есть небольшая строка json, и вы пытаетесь найти ошибку в строке json, я лично предпочитаю использовать доступные инструменты онлайн. Что я обычно делаю, это:
JToken.Parse("1234")! Хорошей идеей будет сначала проверить, начинается ли строка с [или {. Другой альтернативой является использование JObject.Parse()и JArray.Parse().
JToken.Parse("{a:1}")никак не кидать исключение , даже если это является недопустимым JSON - aдолжны быть указаны ( stackoverflow.com/q/949449/3116322 )
использование JContainer.Parse(str) метод, чтобы проверить, является ли str действительным Json. Если это вызывает исключение, то это не правильный Json.
JObject.Parse- Может использоваться для проверки, является ли строка допустимым объектом Json
JArray.Parse- Может использоваться для проверки, является ли строка допустимым массивом Json
JContainer.Parse- Может использоваться для проверки как объекта Json, так и массива
JContainer.Parse("1234");.
Основываясь на ответе Хабиба, вы можете написать метод расширения:
public static bool ValidateJSON(this string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Который затем можно использовать так:
if(stringObject.ValidateJSON())
{
// Valid JSON!
}
JToken.Parse(s);возвращается, trueдаже еслиJToken.Parse(123);
trueдля этого недействительного JSON:{A:{"B": 1}}
Просто чтобы добавить что-то в ответ @ Habib, вы также можете проверить, является ли данный JSON допустимым типом:
public static bool IsValidJson<T>(this string strInput)
{
strInput = strInput.Trim();
if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || //For object
(strInput.StartsWith("[") && strInput.EndsWith("]"))) //For array
{
try
{
var obj = JsonConvert.DeserializeObject<T>(strInput);
return true;
}
catch // not valid
{
return false;
}
}
else
{
return false;
}
}
Я обнаружил, что JToken.Parse неправильно анализирует недопустимый JSON, например:
{
"Id" : ,
"Status" : 2
}
Вставьте строку JSON в http://jsonlint.com/ - она недействительна.
Поэтому я использую:
public static bool IsValidJson(this string input)
{
input = input.Trim();
if ((input.StartsWith("{") && input.EndsWith("}")) || //For object
(input.StartsWith("[") && input.EndsWith("]"))) //For array
{
try
{
//parse the input into a JObject
var jObject = JObject.Parse(input);
foreach(var jo in jObject)
{
string name = jo.Key;
JToken value = jo.Value;
//if the element has a missing value, it will be Undefined - this is invalid
if (value.Type == JTokenType.Undefined)
{
return false;
}
}
}
catch (JsonReaderException jex)
{
//Exception in parsing json
Console.WriteLine(jex.Message);
return false;
}
catch (Exception ex) //some other exception
{
Console.WriteLine(ex.ToString());
return false;
}
}
else
{
return false;
}
return true;
}
{ name : "l am invalid JSON" }
Option Альтернативный вариант, не использующий JSON.Net ⚠️
Для .Net Core / .Net 5 ( в предварительном просмотре на момент написания этой статьи ) можно также использовать System.Text.Jsonпространство имен и анализировать с помощью JsonDocument. Пример - метод расширения, основанный на операциях пространства имен:
public static bool IsJsonValid(this string txt)
{
try { return JsonDocument.Parse(txt) != null; } catch {}
return false;
}
Относительно ответа Тома Бича; Вместо этого я придумал следующее:
public bool ValidateJSON(string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
С использованием следующего:
if (ValidateJSON(strMsg))
{
var newGroup = DeserializeGroup(strMsg);
}
string, но этот ответ действительно должен либо а) не быть здесь, либо б) сказать: «Я использовал ответ Тома Бича » без this, т.е. без его удлинительного элемента) - и этот ответ и ссылки один имеют одинаковую краткость и слабые стороны. Если вы должны сделать это, просто оставьте комментарий к другому ответу.
JToken.Typeдоступно после успешного разбора. Это может быть использовано для устранения части преамбулы в ответах выше и обеспечения более точного контроля за результатом. Абсолютно неверный ввод (например, "{----}".IsValidJson();все равно выдаст исключение).
public static bool IsValidJson(this string src)
{
try
{
var asToken = JToken.Parse(src);
return asToken.Type == JTokenType.Object || asToken.Type == JTokenType.Array;
}
catch (Exception) // Typically a JsonReaderException exception if you want to specify.
{
return false;
}
}
Ссылка на Json.Net для JToken.Type: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm
Вот метод расширения TryParse, основанный на ответе Хабиба:
public static bool TryParse(this string strInput, out JToken output)
{
if (String.IsNullOrWhiteSpace(strInput))
{
output = null;
return false;
}
strInput = strInput.Trim();
if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || //For object
(strInput.StartsWith("[") && strInput.EndsWith("]"))) //For array
{
try
{
output = JToken.Parse(strInput);
return true;
}
catch (JsonReaderException jex)
{
//Exception in parsing json
//optional: LogError(jex);
output = null;
return false;
}
catch (Exception ex) //some other exception
{
//optional: LogError(ex);
output = null;
return false;
}
}
else
{
output = null;
return false;
}
}
Использование:
JToken jToken;
if (strJson.TryParse(out jToken))
{
// work with jToken
}
else
{
// not valid json
}
Я использую это:
internal static bool IsValidJson(string data)
{
data = data.Trim();
try
{
if (data.StartsWith("{") && data.EndsWith("}"))
{
JToken.Parse(data);
}
else if (data.StartsWith("[") && data.EndsWith("]"))
{
JArray.Parse(data);
}
else
{
return false;
}
return true;
}
catch
{
return false;
}
}