Reputation: 33944
How can one validate whether a raw string is valid JSON or just text? I'm using JSON.NET.
Upvotes: 219
Views: 325874
Reputation: 2018
I realize that this answer is 11 years old, which is way before System.Text.Json. There just has to be a better way. Full disclosure, I asked ChatGDP for a means of doing this using C# and the System.Text.JSON namespace, and voila:
{ using System; using System.Text.Json;
public class JsonValidator { public static bool IsValidJson(string json) { if (string.IsNullOrWhiteSpace(json)) { return false; }
try
{
using (JsonDocument document = JsonDocument.Parse(json))
{
// The JSON is valid if we reach this point without exceptions
return true;
}
}
catch (JsonException)
{
// The JSON is invalid
return false;
}
}
public static void Main()
{
string jsonString = "{ \"name\": \"John\", \"age\": 30 }";
if (IsValidJson(jsonString))
{
Console.WriteLine("Valid JSON.");
// Proceed with deserialization
}
else
{
Console.WriteLine("Invalid JSON.");
// Handle the error
}
}
}
}
Upvotes: -3
Reputation: 31576
⚠️ Alternate option using System.Text.Json
⚠️
For .Net Core one can also use the System.Text.Json
namespace and parse using the JsonDocument
. Example is an extension method based on the namespace operations:
public static bool IsJsonValid(this string txt)
{
try { return JsonDocument.Parse(txt) != null; } catch { return false; }
}
Upvotes: 14
Reputation: 51
Sometime
JToken.Parse(jsonString);
doesnt validate the json completely.
instead you can use below method to check validity of json string while reading. Ref : https://www.newtonsoft.com/jsonschema/help/html/ValidatingJson.htm
string json = @"{
'name': 'James',
'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS']
}";
JsonTextReader reader = new JsonTextReader(new StringReader(json));
JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
validatingReader.Schema = JSchema.Parse(schemaJson);
IList<string> messages = new List<string>();
validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message);
JsonSerializer serializer = new JsonSerializer();
Person p = serializer.Deserialize<Person>(validatingReader);
Upvotes: 0
Reputation: 11
Extension that returns a json string even if it returns an exception:
public static string OnlyValidJson(this string strInput) { if (string.IsNullOrWhiteSpace(strInput)) { return @"[""Json is empty""]"; } strInput = strInput.Trim(); if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || (strInput.StartsWith("[") && strInput.EndsWith("]"))) { try { string strEscape = strInput.Replace("\\n", "").Replace("\\r", "").Replace("\n", "").Replace("\r", ""); JToken.Parse(strEscape); return strEscape; } catch (JsonReaderException jex) { return @$"{{""JsonReaderException"":""{jex.Message}""}}"; } catch (Exception ex) { Console.WriteLine(ex.ToString()); return @$"{{""Exception"":""{ex.ToString()}""}}"; } } else { return @"[""Json not start with { or [.""]"; } }
Upvotes: 0
Reputation: 6836
Just to add something to @Habib's answer, you can also check if given JSON is from a valid type:
public static bool IsValidJson<T>(this string strInput)
{
if(string.IsNullOrWhiteSpace(strInput)) return false;
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;
}
}
Upvotes: 18
Reputation: 223187
Through Code:
Your best bet is to use parse inside a try-catch
and catch exception in case of failed parsing. (I am not aware of any TryParse
method).
(Using JSON.Net)
Simplest way would be to Parse
the string using JToken.Parse
, and also to check if the string starts with {
or [
and ends with }
or ]
respectively (added from this answer):
private static bool IsValidJson(string strInput)
{
if (string.IsNullOrWhiteSpace(strInput)) { 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;
}
}
The reason to add checks for {
or [
etc was based on the fact that JToken.Parse
would parse the values such as "1234"
or "'a string'"
as a valid token. The other option could be to use both JObject.Parse
and JArray.Parse
in parsing and see if anyone of them succeeds, but I believe checking for {}
and []
should be easier. (Thanks @RhinoDevel for pointing it out)
Without JSON.Net
You can utilize .Net framework 4.5 System.Json namespace ,like:
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());
}
(But, you have to install System.Json
through Nuget package manager using command: PM> Install-Package System.Json -Version 4.0.20126.16343
on Package Manager Console) (taken from here)
Non-Code way:
Usually, when there is a small json string and you are trying to find a mistake in the json string, then I personally prefer to use available on-line tools. What I usually do is:
Upvotes: 296
Reputation: 5618
I'm using this one:
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;
}
}
Upvotes: 0
Reputation: 1543
Here is a TryParse extension method based on Habib's answer:
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;
}
}
Usage:
JToken jToken;
if (strJson.TryParse(out jToken))
{
// work with jToken
}
else
{
// not valid json
}
Upvotes: 2
Reputation: 7607
JToken.Type
is available after a successful parse. This can be used to eliminate some of the preamble in the answers above and provide insight for finer control of the result. Entirely invalid input (e.g., "{----}".IsValidJson();
will still throw an exception).
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 reference for JToken.Type
: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm
Upvotes: 3
Reputation: 1120
I found that JToken.Parse incorrectly parses invalid JSON such as the following:
{
"Id" : ,
"Status" : 2
}
Paste the JSON string into http://jsonlint.com/ - it is invalid.
So I use:
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;
}
Upvotes: 14
Reputation: 862
Use JContainer.Parse(str)
method to check if the str is a valid Json. If this throws exception then it is not a valid Json.
JObject.Parse
- Can be used to check if the string is a valid Json object
JArray.Parse
- Can be used to check if the string is a valid Json Array
JContainer.Parse
- Can be used to check for both Json object & Array
Upvotes: 45
Reputation: 43
This method doesn't require external libraries
using System.Web.Script.Serialization;
bool IsValidJson(string json)
{
try {
var serializer = new JavaScriptSerializer();
dynamic result = serializer.DeserializeObject(json);
return true;
} catch { return false; }
}
Upvotes: 0
Reputation: 661
Regarding Tom Beech's answer; I came up with the following instead:
public bool ValidateJSON(string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
With a usage of the following:
if (ValidateJSON(strMsg))
{
var newGroup = DeserializeGroup(strMsg);
}
Upvotes: 3
Reputation: 2389
Building on Habib's answer, you could write an extension method:
public static bool ValidateJSON(this string s)
{
try
{
JToken.Parse(s);
return true;
}
catch (JsonReaderException ex)
{
Trace.WriteLine(ex);
return false;
}
}
Which can then be used like this:
if(stringObject.ValidateJSON())
{
// Valid JSON!
}
Upvotes: 41