JSON.NETを使用して文字列が有効なJSONであることを確認する方法


147

生の弦があります。文字列が有効なJSONかどうかを検証したいだけです。JSON.NETを使用しています。

回答:


207

コードを通じて:

あなたの最善の策は、内部で解析を使用し、解析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());
}

(ただし、パッケージマネージャーコンソールでSystem.Json次のコマンドを使用してNugetパッケージマネージャーからインストールする必要がありますPM> Install-Package System.Json -Version 4.0.20126.16343ここから取得)

非コードの方法:

通常、小さなjson文字列があり、json文字列の間違いを見つけようとしている場合、私は個人的に利用可能なオンラインツールを使用することを好みます。私が通常行うことは次のとおりです。


3
実行時にこれを行う方法。検証目的でtry catchを使用したくない
user960567

1
JSONのスキーマを作成し、後でそのスキーマに対して検証できます。Json.NET3.5 Beta 2 – JSONスキーマ検証
Habib

1
tryブロックなしでそれを行う方法はありますか?未知のものを扱っていない限り、tryブロックを使用しません。JsonConvert.TryDeserializeObjectのようなものを探しています。運用上の試行キャッチは、単なる悪いコードです。
ヨルダン

1
JSON.Netの使用:これは例外をスローしませJToken.Parse("1234")!文字列が[またはで始まる場合は、最初に確認することをお勧めし{ます。別の選択肢は、使用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
Parse()メソッドがこのレベルで宣言されているため、JContainerの代わりにタイプJTokenを使用する方がより有効です
Denis The Menace

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 2016

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のドキュメントであり、ポイント5 JSONは値の下には、値が値としてnullを取ることができます見ることができます。jsonlintインタプリタのバグです
ドミニクレンバーガー、

4
ドミニク、あなたがリンクしたスペックの私の読み取りによるJSON値は、リテラルnullテキストがnull値を表す、いくつかの有効なトークンを持っている必要があります。有効な値は、参照した仕様に従って「オブジェクト、配列、数値、文字列、true、false、またはnull」です。AFAICS値トークンのない有効な値はありません。
Kirtlander 2017年

これは、次のような無効なJSONでも問題ないようです{ name : "l am invalid JSON" }
Jon49

2

⚠️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つは、同一の簡潔さと弱さを持っています。この点を指摘する必要がある場合は、他の回答にコメントを付けてください。
Ruben Bartelink

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;
     }
  }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.