如何使用JSON.NET确保字符串是有效的JSON

本文关键字:JSON 有效 字符串 确保 何使用 NET | 更新日期: 2023-09-27 18:00:24

我有一个原始字符串。我只想验证字符串是否是有效的JSON。我使用的是JSON.NET。

如何使用JSON.NET确保字符串是有效的JSON

通过代码:

最好在try-catch中使用parse,并在解析失败的情况下捕获异常(我不知道任何TryParse方法)

(使用JSON.Net)

最简单的方法是使用JToken.ParseParse字符串,还可以检查字符串是否以{[开始,并分别以}]结束(从该答案添加)

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;
    }
}

{[等添加检查的原因是,JToken.Parse会将"1234""'a string'"等值解析为有效令牌。另一种选择是在解析中同时使用JObject.ParseJArray.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());
}

(但是,您必须使用PackageManager控制台上的命令:PM> Install-Package System.Json -Version 4.0.20126.16343通过Nuget软件包管理器安装System.Json(取自此处)

非代码方式:

通常,当有一个小的json字符串,并且您试图在json字符串中找到错误时,我个人更喜欢使用可用的在线工具。我通常做的是:

  • 在JSONLint中粘贴JSON字符串JSON验证器,并查看它是一个有效的JSON
  • 稍后将正确的JSON复制到http://json2csharp.com/和为它生成一个模板类,然后反序列化它使用JSON.Net

使用JContainer.Parse(str)方法检查str是否是有效的Json。若这抛出异常,那个么它就不是一个有效的Json。

JObject.Parse-可用于检查字符串是否为有效的Json对象
JArray.Parse-可用于检查字符串是否为有效的Json数组
CCD_ 23-可用于检查Json对象和;数组

基于Habib的答案,您可以编写一个扩展方法:

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!
}

为了给@Habib的答案添加一些内容,您还可以检查给定的JSON是否来自有效类型:

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;
    }
}

我发现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;
}

⚠️使用System.Text.Json的备用选项⚠️

对于.Net Core,还可以使用System.Text.Json名称空间并使用JsonDocument进行解析。示例是基于命名空间操作的扩展方法:

public static bool IsJsonValid(this string txt)
{
    try { return JsonDocument.Parse(txt) != null; } catch {}
    return false;
}

关于Tom Beech的回答;相反,我想出了以下方法:

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);
}

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;
        }
    }

JToken.Type的Json.Net参考:https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm

此方法不需要外部库

using System.Web.Script.Serialization;
bool IsValidJson(string json)
    {
        try {
            var serializer = new JavaScriptSerializer();
            dynamic result = serializer.DeserializeObject(json);
            return true;
        } catch { return false; }
    }

这里有一个基于Habib答案的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;
     }
  }

即使返回异常也会返回json字符串的扩展:

公共静态字符串OnlyValidJson(此字符串strInput){if(string.IsNullOrWhiteSpace(strInput)){return@"["Json为空"]";}strInput=strInput.Trim();if((strInput.StartsWith("{")&&strInput.EndsWith||(strInput.StartsWith("[")&&strInput.EndsWith("]")){尝试{string strEscape=strInput.Replace("''''n",";JToken.Parse(strEscape);return strEscape;}catch(JsonReaderException jex){return@$"{{"JsonReaderException":"{jex.Message}"}}";}catch(异常ex){Console.WriteLine(例如ToString());return@$"{{"Exception":"{ex.ToString()}"}}";}}其他的{return@"["Json不以{或[."]开头;}}

有时JToken.Parse(jsonString);不会完全验证json。

相反,您可以使用以下方法在读取时检查json字符串的有效性。参考编号: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);