Tengo una cuerda cruda. Solo quiero validar si la cadena es JSON válida o no. Estoy usando JSON.NET.
Tengo una cuerda cruda. Solo quiero validar si la cadena es JSON válida o no. Estoy usando JSON.NET.
Respuestas:
A través del código:
Su mejor opción es usar el análisis dentro de ay try-catch
capturar una excepción en caso de un análisis fallido. (No conozco ningún TryParse
método) .
(Usando JSON.Net)
La forma más simple sería usar Parse
la cadena JToken.Parse
y también verificar si la cadena comienza con {
o [
y termina con }
o ]
respectivamente (agregado de esta respuesta ) :
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;
}
}
La razón para agregar controles para {
o [
etc. se basó en el hecho de que JToken.Parse
analizaría los valores como "1234"
o "'a string'"
como un token válido. La otra opción podría ser usar ambos JObject.Parse
y JArray.Parse
analizar y ver si alguno de ellos tiene éxito, pero creo que verificar {}
y []
debería ser más fácil. (Gracias @RhinoDevel por señalarlo )
Sin JSON.Net
Puede utilizar el espacio de nombres .Net framework 4.5 System.Json , como:
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());
}
(Pero, debe instalar a System.Json
través del administrador de paquetes Nuget usando el comando: PM> Install-Package System.Json -Version 4.0.20126.16343
en la Consola del Administrador de paquetes) (tomado de aquí )
Manera sin código:
Por lo general, cuando hay una pequeña cadena json y estás tratando de encontrar un error en la cadena json, yo personalmente prefiero usar las herramientas en línea disponibles. Lo que suelo hacer es:
JToken.Parse("1234")
! Puede ser una buena idea verificar primero, si la cadena comienza con [
o {
. Otra alternativa es el uso JObject.Parse()
y JArray.Parse()
.
JToken.Parse("{a:1}")
no no lanzar una excepción a pesar de que esto es válido JSON - a
debe ser citado ( stackoverflow.com/q/949449/3116322 )
Use el JContainer.Parse(str)
método para verificar si el str es un Json válido. Si esto arroja una excepción, entonces no es un Json válido.
JObject.Parse
- Se puede usar para verificar si la cadena es un objeto Json válido
JArray.Parse
- Se puede usar para verificar si la cadena es una matriz Json válida
JContainer.Parse
- Se puede usar para verificar tanto el objeto Json como la matriz
JContainer.Parse("1234");
.
Sobre la base de la respuesta de Habib, podría escribir un método de extensión:
public static bool ValidateJSON(this string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Que luego se puede usar así:
if(stringObject.ValidateJSON())
{
// Valid JSON!
}
JToken.Parse(s);
vuelve true
incluso siJToken.Parse(123);
true
para este inválido JSON
:{A:{"B": 1}}
Solo para agregar algo a la respuesta de @ Habib, también puede verificar si JSON dado es de un tipo válido:
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;
}
}
Descubrí que JToken.Parse analiza incorrectamente JSON inválido como el siguiente:
{
"Id" : ,
"Status" : 2
}
Pegue la cadena JSON en http://jsonlint.com/ , no es válida.
Entonces 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" }
⚠️ Opción alternativa que no usa JSON.Net ⚠️
Para .Net Core / .Net 5 ( en la vista previa al momento de escribir esto ) también se puede usar el System.Text.Json
espacio de nombres y analizar usando JsonDocument
. El ejemplo es un método de extensión basado en las operaciones de espacio de nombres:
public static bool IsJsonValid(this string txt)
{
try { return JsonDocument.Parse(txt) != null; } catch {}
return false;
}
Con respecto a la respuesta de Tom Beech; En su lugar, se me ocurrió lo siguiente:
public bool ValidateJSON(string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Con un uso de lo siguiente:
if (ValidateJSON(strMsg))
{
var newGroup = DeserializeGroup(strMsg);
}
string
, pero esta respuesta realmente debería a) no estar aquí o b) decir " Usé la respuesta de Tom Beech " sin el this
, es decir, sin convertirlo en un miembro de extensión), tanto esta respuesta como la referenciada tienen una brevedad y debilidad idénticas. Si debe hacer este punto, simplemente ponga un comentario en la otra respuesta.
JToken.Type
está disponible después de un análisis exitoso. Esto se puede utilizar para eliminar algunos de los preámbulos en las respuestas anteriores y proporcionar información para un control más preciso del resultado. Entrada completamente inválida (por ejemplo, "{----}".IsValidJson();
todavía arrojará una excepción).
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;
}
}
Referencia de Json.Net para JToken.Type
: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm
Aquí hay un método de extensión TryParse basado en la respuesta de 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
}
Estoy usando este:
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;
}
}