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

(하지만 패키지 관리자 콘솔에서 System.Json다음 명령을 사용하여 Nuget 패키지 관리자를 통해 설치해야 함 PM> Install-Package System.Json -Version 4.0.20126.16343) ( 여기 에서 가져옴 )

비 코드 방식 :

일반적으로 작은 json 문자열이 있고 json 문자열에서 실수를 찾으려고 할 때 개인적 으로 사용 가능한 온라인 도구를 선호합니다. 내가 보통하는 일은 :

  • JSONLint에 JSON 문자열 붙여 넣기 JSON Validator 는 유효한 JSON인지 확인합니다.
  • 나중에 올바른 JSON을 http://json2csharp.com/에 복사하고 이에 대한 템플릿 클래스를 생성 한 다음 JSON.Net을 사용하여 직렬화 해제하십시오.

3
런타임에 어떻게 할 수 있습니까? 나는 검증 목적으로 시도 캐치를 사용하지 않으
user960567

1
JSON에 대한 스키마를 만들고 나중에 해당 스키마에 대해 확인할 수 있습니다. Json.NET 3.5 베타 2 – JSON 스키마 유효성 검사
Habib

1
try 블록없이 그것을 할 수있는 방법이 있습니까? 알 수없는 처리하지 않는 한 try 블록을 사용하지 않습니다. JsonConvert.TryDeserializeObject와 같은 것을 찾고 있습니다. 작동 시도 어획은 단순한 나쁜 코드입니다.
Jordan

1
JSON.Net 사용 : 예외가 발생 하지 않습니다 : JToken.Parse("1234")! 문자열이 [또는로 시작하면 먼저 확인하는 것이 좋습니다 {. 또 다른 대안은 use JObject.Parse()JArray.Parse()입니다.
RhinoDevel

1
JToken.Parse("{a:1}")JSON이 유효하지 않더라도 예외가 발생 하지 않습니다 - a따옴표로 묶어야합니다 ( stackoverflow.com/q/949449/3116322 )
Ande

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

오답, JContainer.Parse는 모든 작업
Toolkit

19

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

1
JToken.Parse(s);반환 true하더라도JToken.Parse(123);
확인 Makeluv

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 값 아래에서 값으로 null을 사용할 수 있습니다. . 그래서 jsonlint 인터프리터의 버그
Dominik Lemberger

4
Dominik, 링크 한 사양을 읽은 JSON 값은 유효한 토큰이 있어야하며 리터럴 null 텍스트는 null 값을 나타냅니다. 참조한 사양에 따라 유효한 값은 "객체, 배열, 숫자, 문자열, true, false 또는 null"입니다. AFAICS 가치 토큰이없는 유효한 가치가 없습니다.
Kirtlander

이것은 유효하지 않은 JSON과 같이 { name : "l am invalid JSON" }
괜찮을

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
이것은 새로운 것이 아닙니다. 확장 방법이 확장 방법이 아니 었습니다. Tom Beech의 답변은 이미 필요한 것을 달성 할 수 있습니다 (일반적으로,이 종류의 확장 방법을 추가하는 것에 싫증이 string났지만이 답변은 a) 여기 있지 않거나 b) " Tom Beech 's answer "없이 ( this즉, 확장 멤버로 만들지 않음)-이 답변과 참조 된 답변은 동일한 간결성과 약점을 갖습니다. 이 점을 지적해야하는 경우 다른 답변에 의견을 적어주십시오.
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.Type: https://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.