Mam surowy sznurek. Chcę tylko sprawdzić, czy ciąg jest prawidłowym JSON, czy nie. Używam JSON.NET.
Mam surowy sznurek. Chcę tylko sprawdzić, czy ciąg jest prawidłowym JSON, czy nie. Używam JSON.NET.
Odpowiedzi:
Poprzez kod:
Najlepszym rozwiązaniem jest użycie parsowania wewnątrz try-catch
wyjątku i catch w przypadku niepowodzenia parsowania. (Nie znam żadnej TryParse
metody) .
(Przy użyciu JSON.Net)
Najprostszym sposobem byłoby Parse
użycie łańcucha JToken.Parse
, a także sprawdzenie, czy ciąg zaczyna się od {
lub [
i kończy odpowiednio na }
lub (dodane z tej odpowiedzi ) :]
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;
}
}
Powodem dodania czeków dla {
lub [
itp. Był fakt, JToken.Parse
że przeanalizowałoby wartości, takie jak "1234"
lub "'a string'"
jako prawidłowy token. Inną opcją może być użycie obu JObject.Parse
i JArray.Parse
podczas analizowania i sprawdzenie, czy komuś się powiedzie, ale uważam, że sprawdzanie {}
i []
powinno być łatwiejsze. (Dzięki @RhinoDevel za wskazanie tego)
Bez JSON.Net
Możesz wykorzystać przestrzeń nazw System.Json .Net framework 4.5 , na przykład:
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());
}
(Ale musisz zainstalować System.Json
przez menedżera pakietów Nuget za pomocą polecenia: PM> Install-Package System.Json -Version 4.0.20126.16343
w konsoli Menedżera pakietów) (pobrane stąd )
Sposób niekodowany:
Zwykle, gdy występuje mały ciąg json i próbujesz znaleźć błąd w łańcuchu json, wtedy osobiście wolę użyć dostępnych narzędzi on-line. Zwykle robię:
JToken.Parse("1234")
! Warto najpierw sprawdzić, czy ciąg znaków zaczyna się od [
lub {
. Inną alternatywą jest użycie JObject.Parse()
i JArray.Parse()
.
JToken.Parse("{a:1}")
czy nie rzucić wyjątek chociaż jest nieprawidłowy JSON - a
powinny być cytowane ( stackoverflow.com/q/949449/3116322 )
Użyj JContainer.Parse(str)
metody, aby sprawdzić, czy str jest prawidłowym plikiem Json. Jeśli zgłasza wyjątek, nie jest to poprawna Json.
JObject.Parse
- Może być użyty do sprawdzenia, czy ciąg jest prawidłowym obiektem Json
JArray.Parse
- Może być użyty do sprawdzenia, czy ciąg jest prawidłową tablicą Json
JContainer.Parse
- Może być użyty do sprawdzenia zarówno obiektu Json, jak i tablicy
JContainer.Parse("1234");
.
Opierając się na odpowiedzi Habiba, możesz napisać metodę rozszerzającą:
public static bool ValidateJSON(this string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Które można następnie wykorzystać w następujący sposób:
if(stringObject.ValidateJSON())
{
// Valid JSON!
}
JToken.Parse(s);
zwraca, true
nawet jeśliJToken.Parse(123);
true
za to nieważne JSON
:{A:{"B": 1}}
Aby dodać coś do odpowiedzi @ Habib, możesz również sprawdzić, czy podany JSON pochodzi z prawidłowego typu:
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;
}
}
Okazało się, że JToken.Parse niepoprawnie analizuje nieprawidłowy kod JSON, na przykład:
{
"Id" : ,
"Status" : 2
}
Wklej ciąg JSON do http://jsonlint.com/ - jest nieprawidłowy.
Więc używam:
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" }
⚠️ Alternatywna opcja bez użycia JSON.Net ⚠️
W przypadku .Net Core / .Net 5 ( w wersji zapoznawczej w chwili pisania tego tekstu ) można również użyć System.Text.Json
przestrzeni nazw i przeanalizować za pomocą JsonDocument
. Przykład to metoda rozszerzenia oparta na operacjach w przestrzeni nazw:
public static bool IsJsonValid(this string txt)
{
try { return JsonDocument.Parse(txt) != null; } catch {}
return false;
}
Odnośnie odpowiedzi Toma Beecha; Zamiast tego wymyśliłem:
public bool ValidateJSON(string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Korzystając z:
if (ValidateJSON(strMsg))
{
var newGroup = DeserializeGroup(strMsg);
}
string
, ale ta odpowiedź naprawdę powinna albo a) nie być tutaj lub b) powiedzieć „Użyłem odpowiedzi Toma Beecha ” bez the this
, czyli bez robienia z niej elementu rozszerzenia) - zarówno ta odpowiedź, jak i ta, do której się odwołujemy, mają identyczną zwięzłość i słabości. Jeśli musisz to zaznaczyć, po prostu dodaj komentarz do drugiej odpowiedzi.
JToken.Type
jest dostępny po pomyślnym przeanalizowaniu. Można to wykorzystać do wyeliminowania części preambuły z powyższych odpowiedzi i zapewnienia wglądu w lepszą kontrolę wyniku. Całkowicie nieprawidłowe dane wejściowe (np. "{----}".IsValidJson();
Nadal będzie zgłaszać wyjątek).
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;
}
}
Dokumentacja Json.Net dla JToken.Type
: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm
Oto metoda rozszerzenia TryParse oparta na odpowiedzi Habiba:
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;
}
}
Stosowanie:
JToken jToken;
if (strJson.TryParse(out jToken))
{
// work with jToken
}
else
{
// not valid json
}
Używam tego:
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;
}
}