簡體   English   中英

如何使用 JSON.NET 確保字符串有效 JSON

[英]How to make sure that string is valid JSON using JSON.NET

我有一個原始字符串。 我只想驗證字符串是否有效 JSON 。 我正在使用 JSON.NET。

通過代碼:

最好的辦法是在try-catch使用 parse 並在解析失敗時捕獲異常。 (我不知道任何TryParse方法)

(使用 JSON.Net)

最簡單的方法是使用JToken.Parse Parse字符串,並分別檢查字符串是否以{[開頭並以}]結尾(從此答案中添加)

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

(但是,您必須使用以下命令通過 Nuget 包管理器安裝System.JsonPM> Install-Package System.Json -Version 4.0.20126.16343 on Package Manager Console) (取自此處

非代碼方式:

通常,當有一個小的 json 字符串並且您試圖在 json 字符串中查找錯誤時,那么我個人更喜歡使用可用的在線工具。 我通常做的是:

使用JContainer.Parse(str)方法檢查 str 是否是有效的 Json。 如果這引發異常,則它不是有效的 Json。

JObject.Parse - 可用於檢查字符串是否為有效的 Json 對象
JArray.Parse - 可用於檢查字符串是否為有效的 Json 數組
JContainer.Parse - 可用於檢查 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;
}

關於湯姆·比奇的回答; 我想出了以下內容:

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 : JToken.Type

此方法不需要外部庫

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 字符串的擴展:

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 [.""]}";
            }
        }

有時JToken.Parse(jsonString); 沒有完全驗證 json。

相反,您可以使用以下方法在閱讀時檢查 json 字符串的有效性。 參考: https://www.newtonsoft.com/jsonschema/help/html/ValidatingJson.htm

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM