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


147

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

Answers:


207

通过代码:

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

(使用JSON.Net)

最简单的方法是Parse使用JToken.Parse,并检查字符串是否分别以或开头,以{[结束(从此答案中添加}]

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

添加{[等等的检查的原因是基于这样的事实:JToken.Parse它将解析诸如"1234""'a string'"作为有效令牌的值。另一种选择可能是同时使用JObject.Parse,并JArray.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());
}

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

非代码方式:

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


3
如何在运行时执行此操作。我不想将try catch用于验证目的
user960567 2013年

1
您可以为JSON创建一个架构,然后再针对该架构进行验证,请参阅:Json.NET 3.5 Beta 2 – JSON架构验证
Habib 2013年

1
有没有尝试块的方法吗?除非我要处理未知数,否则我不会使用try块。我正在寻找类似JsonConvert.TryDeserializeObject的东西。操作尝试捕获只是普通的错误代码。
约旦

1
使用JSON.Net:这并不会抛出异常:JToken.Parse("1234")!如果string以[或开头,则最好先检查一下{。另一种选择是use JObject.Parse()JArray.Parse()
RhinoDevel 2015年

1
JToken.Parse("{a:1}")没有引发异常,即使这是无效的JSON - a应该被引用(stackoverflow.com/q/949449/3116322
安德

31

使用JContainer.Parse(str)方法检查str是否为有效的Json。如果这引发异常,则它不是有效的Json。

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


17
相反JContainer的它更有效的使用,因为解析型JToken()方法被声明在这个水平
丹尼斯的威胁

6
我假设您正在谈论JSON.Net:JContainer不能那样工作,因为它不会在所有需要的情况下引发异常。范例:JContainer.Parse("1234");
RhinoDevel 2015年

错误的答案,JContainer.Parse可以处理任何内容
Toolkit

19

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

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

1
JToken.Parse(s);true即使返回JToken.Parse(123);
Make Makeluv '16

2
true此无效的返回值JSON{A:{"B": 1}}
Mehdi Dehghani

不错的扩展方法:)尽管可能最好将其命名为“ IsValidJson”。
Mladen B.

11

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

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

7

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

那不是无效的JSON字符串ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf,这是JSON标准ECMA的文档,在Point 5 JSON Values下,您可以看到一个值可以将null用作值。因此,这只是jsonlint解释器中的一个错误
Dominik Lemberger '17

4
Dominik,根据我对您所链接的规范的理解,它是一个JSON值,必须具有一些有效的令牌,文字上的空文本表示一个空值。根据您引用的规范,有效值为“对象,数组,数字,字符串,true,false或null”。AFAICS没有有效值,没有价值令牌。
Kirtlander

看起来像这样的无效JSON可以正常使用{ name : "l am invalid JSON" }
Jon49 '19

2

Not️备用选项未使用JSON.Net⚠️

对于.Net Core / .Net 5(在撰写本文时预览),也可以使用System.Text.Json名称空间并使用进行解析JsonDocument。示例是基于名称空间操作的扩展方法:

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

    return false;
}

1

关于汤姆·比奇的回答;我想出了以下内容:

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

3
这不是什么新颖的方法-您使扩展方法不是扩展方法。汤姆·比奇的答案已经可以满足您的需求(通常,我也string不太愿意添加此类扩展方法,但是这个答案确实应该a)不在此处或b)说“我用汤姆·比奇的答案 ”而无需的this,没有使它的扩展成员),即-无论这个答案和参考的一个具有相同的简洁和弱点。如果您必须指出这一点,只需对另一个答案发表评论。
鲁宾·巴特林克

1

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

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


0

此方法不需要外部库

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

0

这是一个基于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
}

0

我正在使用这个:

  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;
     }
  }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.