Ho una stringa grezza. Voglio solo confermare se la stringa è valida o meno JSON. Sto usando JSON.NET.
Ho una stringa grezza. Voglio solo confermare se la stringa è valida o meno JSON. Sto usando JSON.NET.
Risposte:
Tramite codice:
La soluzione migliore è utilizzare l'analisi all'interno di a try-catch
e rilevare l'eccezione in caso di analisi non riuscita. (Non sono a conoscenza di alcun TryParse
metodo) .
(Utilizzando JSON.Net)
Il modo più semplice sarebbe quello di Parse
utilizzare la stringa JToken.Parse
e anche di verificare se la stringa inizia con {
o [
e termina con }
o ]
rispettivamente (aggiunto da questa risposta ) :
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;
}
}
Il motivo per aggiungere controlli per {
o [
ecc. Era basato sul fatto che JToken.Parse
avrebbe analizzato i valori come "1234"
o "'a string'"
come token valido. L'altra opzione potrebbe essere quella di utilizzare entrambi JObject.Parse
e JArray.Parse
nell'analisi e vedere se qualcuno di loro ha esito positivo, ma credo che il controllo {}
e []
dovrebbe essere più semplice. (Grazie @RhinoDevel per indicare fuori)
Senza JSON.Net
È possibile utilizzare lo spazio dei nomi System.Json di .Net framework 4.5 , come:
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());
}
(Ma devi installare System.Json
tramite Nuget Package Manager usando il comando: PM> Install-Package System.Json -Version 4.0.20126.16343
su Package Manager Console) (preso da qui )
Modo senza codice:
Di solito, quando c'è una piccola stringa JSON e stai cercando di trovare un errore nella stringa JSON, preferisco personalmente utilizzare gli strumenti online disponibili. Quello che faccio di solito è:
JToken.Parse("1234")
! Potrebbe essere una buona idea controllare prima, se la stringa inizia con [
o {
. Un'altra alternativa è l'uso JObject.Parse()
e JArray.Parse()
.
JToken.Parse("{a:1}")
non senza lanciare un'eccezione, anche se questo è JSON valido - a
dovrà essere espresso ( stackoverflow.com/q/949449/3116322 )
Utilizzare il JContainer.Parse(str)
metodo per verificare se str è un Json valido. Se questo genera un'eccezione, non è un Json valido.
JObject.Parse
- Può essere usato per verificare se la stringa è un oggetto Json valido
JArray.Parse
- Può essere usato per controllare se la stringa è un array Json valido
JContainer.Parse
- Può essere usato per controllare sia l'oggetto Json sia l'array
JContainer.Parse("1234");
.
Sulla base della risposta di Habib, è possibile scrivere un metodo di estensione:
public static bool ValidateJSON(this string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Che può quindi essere utilizzato in questo modo:
if(stringObject.ValidateJSON())
{
// Valid JSON!
}
JToken.Parse(s);
ritorna true
anche seJToken.Parse(123);
true
per questo invalido JSON
:{A:{"B": 1}}
Solo per aggiungere qualcosa alla risposta di @ Habib, puoi anche verificare se un dato JSON proviene da un tipo valido:
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;
}
}
Ho scoperto che JToken.Parse analizza erroneamente JSON non valido come il seguente:
{
"Id" : ,
"Status" : 2
}
Incolla la stringa JSON in http://jsonlint.com/ - non è valida.
Quindi io uso:
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" }
⚠️ Opzione alternativa che non utilizza JSON.Net ⚠️
Per .Net Core / .Net 5 ( in anteprima al momento della stesura di questo documento ) si può anche usare lo System.Text.Json
spazio dei nomi e analizzare usando il JsonDocument
. Esempio è un metodo di estensione basato sulle operazioni dello spazio dei nomi:
public static bool IsJsonValid(this string txt)
{
try { return JsonDocument.Parse(txt) != null; } catch {}
return false;
}
Per quanto riguarda la risposta di Tom Beech; Invece ho pensato a quanto segue:
public bool ValidateJSON(string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Con un utilizzo di quanto segue:
if (ValidateJSON(strMsg))
{
var newGroup = DeserializeGroup(strMsg);
}
string
, ma questa risposta dovrebbe o a) non essere qui oppure b) dire "Ho usato la risposta di Tom Beech " senza il this
, cioè senza renderlo un membro di estensione) - sia questa risposta che quella referenziata hanno identica brevità e punti deboli. Se devi fare questo punto, inserisci un commento sull'altra risposta.
JToken.Type
è disponibile dopo un'analisi riuscita. Questo può essere usato per eliminare parte del preambolo nelle risposte sopra e fornire informazioni per un controllo più preciso del risultato. Immissione totalmente non valida (ad es. "{----}".IsValidJson();
Genererà comunque un'eccezione).
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;
}
}
Riferimento Json.Net per JToken.Type
: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm
Ecco un metodo di estensione TryParse basato sulla risposta di Habib:
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;
}
}
Uso:
JToken jToken;
if (strJson.TryParse(out jToken))
{
// work with jToken
}
else
{
// not valid json
}
Sto usando questo:
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;
}
}