JSON.NET kullanarak dizenin geçerli JSON olduğundan nasıl emin olunur


147

Ham bir ipim var. Ben sadece dize geçerli JSON olup olmadığını doğrulamak istiyorum. JSON.NET kullanıyorum.

Yanıtlar:


207

Kod Üzerinden:

En iyi seçeneğiniz, ayrıştırma işleminde a çözümlemesini kullanmak ve ayrıştırmada try-catchistisna yakalamaktır. (Herhangi bir TryParseyöntemin farkında değilim ) .

(JSON.Net kullanarak)

En basit yol Parse, dizeyi kullanarak JToken.Parseve ayrıca dizenin {veya [ile başlayıp başlamadığını veya sona erdiğini }veya ]sırasıyla bitip bitmediğini kontrol etmektir (bu yanıttan eklenmiştir ) :

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

Sebebi kontrolleri eklemek {veya [vb gerçeğine dayanıyordu JToken.Parsegibi değerleri ayrıştırmak olurdu "1234"ya "'a string'"geçerli bir ifadesi olarak. Diğer seçenek, hem ayrıştırmada hem de ayrıştırmada kullanmak JObject.Parseve JArray.Parseherhangi birinin başarılı olup olmadığını görmek olabilir, ancak kontrol etmenin {}ve []daha kolay olması gerektiğine inanıyorum . (Teşekkürler için @RhinoDevel işaret dışarı)

JSON.Net olmadan

Net framework 4.5 System.Json ad alanını aşağıdaki gibi kullanabilirsiniz:

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

(Ancak, Paket Yöneticisi Konsolu'nda şu System.Jsonkomutu kullanarak Nuget paket yöneticisi aracılığıyla yüklemeniz gerekir PM> Install-Package System.Json -Version 4.0.20126.16343) ( buradan alınır )

Kod olmayan yol:

Genellikle, küçük bir json dizesi olduğunda ve json dizesinde bir hata bulmaya çalıştığınızda, kişisel olarak mevcut on-line araçları kullanmayı tercih ederim. Genelde yaptığım şey:

  • JSON dizesini JSONLint'e yapıştırın JSON Doğrulayıcı ve geçerli bir JSON olup olmadığına bakın.
  • Daha sonra doğru JSON'u http://json2csharp.com/ adresine kopyalayın ve bunun için bir şablon sınıfı oluşturun ve ardından JSON.Net kullanarak serisinin serisini kaldırın.

3
Bunu çalışma zamanında nasıl yapabilirsiniz. Doğrulama amacıyla try catch kullanmak istemiyorum
user960567


1
Deneme bloğu olmadan yapmanın herhangi bir yolu var mı? Bir bilinmeyenle uğraşmadıkça try blokları kullanmıyorum. JsonConvert.TryDeserializeObject gibi bir şey arıyorum. Operasyonel deneme yakalama sadece düz kötü kod.
Ürdün

1
Json.NET kullanma: Bu mu değil bir istisna: JToken.Parse("1234")! Dize [veya ile başlıyorsa, önce kontrol etmek iyi bir fikir olabilir {. Başka bir alternatif kullanım JObject.Parse()ve JArray.Parse().
RhinoDevel

1
JToken.Parse("{a:1}")yok değil bu geçersiz JSON olsa istisna - aalıntılanan edilmelidir ( stackoverflow.com/q/949449/3116322 )
Ande

31

JContainer.Parse(str)Str'nin geçerli bir Json olup olmadığını kontrol etmek için yöntemi kullanın . Bu bir istisna atarsa, geçerli bir Json değildir.

JObject.Parse- Dizenin geçerli bir Json nesnesi
JArray.Parseolup olmadığını kontrol etmek için kullanılabilir - Dizenin geçerli bir Json Dizisi
JContainer.Parseolup olmadığını kontrol etmek için kullanılabilir - Hem Json nesnesi hem de Array öğesini kontrol etmek için kullanılabilir


17
Parse () yöntemi bu düzeyde bildirildiğinden JContainer yerine JToken türünü kullanmak daha geçerlidir
Denis The Menace

6
Sana JSON.Net bahsediyoruz varsayarak ediyorum: JContainer yok değil tüm istediği durumlarda bir istisna değildir, çünkü bu şekilde çalışmaz. Örnek: JContainer.Parse("1234");.
RhinoDevel

Yanlış cevap, JContainer.Parse her şey üzerinde çalışıyor
Toolkit

19

Habib'in cevabına dayanarak bir uzatma yöntemi yazabilirsiniz:

public static bool ValidateJSON(this string s)
{
    try
    {
        JToken.Parse(s);
        return true;
    }
    catch (JsonReaderException ex)
    {
        Trace.WriteLine(ex);
        return false;
    }
}

Hangisi daha sonra şu şekilde kullanılabilir:

if(stringObject.ValidateJSON())
{
    // Valid JSON!
}

1
JToken.Parse(s);truebile geri dönerJToken.Parse(123);
Makeluv

2
trueBu geçersiz iade JSON:{A:{"B": 1}}
Mehdi Dehghani

Güzel uzantısı yöntemi var :) Ama muhtemelen daha iyi "IsValidJson" olarak adlandırılır.
Mladen

11

@ Habib'in cevabına bir şeyler eklemek için JSON'un geçerli bir türden olup olmadığını da kontrol edebilirsiniz:

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 yanlış aşağıdaki gibi geçersiz JSON ayrıştırır bulundu:

{
"Id" : , 
"Status" : 2
}

JSON dizesini http://jsonlint.com/ içine yapıştırın - geçersiz.

Bu yüzden kullanıyorum:

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

Bu geçersiz bir JSON String değil ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf Burada JSON Standard ECMA'nın dokümantasyonu ve Point 5 JSON Değerleri altında bir değerin değer olarak boş olabileceğini görebilirsiniz . Bu jsonlint tercümanında sadece bir hata
Dominik Lemberger

4
Dominik, bağladığınız spekülasyonu okuduğuma göre bir JSON değeri geçerli bir jetona sahip olmalı ve değişmez boş metin null değeri temsil etmelidir. Geçerli değerler, başvuruda bulunduğunuz özelliklere göre "bir nesne, dizi, sayı, dize, true, false veya null". AFAICS, değer belirteci olmadan geçerli bir değer yok.
Kirtlander

Bu gibi görünüyor geçersiz JSON ile Tamam olacak gibi görünüyor{ name : "l am invalid JSON" }
Jon49

2

Option️ Alternatif Seçenek JSON.Net Kullanmıyor ⚠️

.Net Core / .Net 5 için ( bu yazıdan itibaren önizlemede ), System.Text.Jsonad alanını kullanabilir ve JsonDocument. Örnek, ad alanı işlemlerine dayalı bir uzantı yöntemidir:

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

    return false;
}

1

Tom Beech'in cevabı ile ilgili olarak; Bunun yerine aşağıdakileri buldum:

public bool ValidateJSON(string s)
{
    try
    {
        JToken.Parse(s);
        return true;
    }
    catch (JsonReaderException ex)
    {
        Trace.WriteLine(ex);
        return false;
    }
}

Aşağıdakilerin kullanımı ile:

if (ValidateJSON(strMsg))
{
    var newGroup = DeserializeGroup(strMsg);
}

3
Bu yeni bir şey değil - bir uzantı yöntemi değil, bir uzantı yöntemi yaptınız. Tom Beech'in cevabı ihtiyacınız olanı zaten başarabilir (Genel olarak, bu tür uzatma yöntemlerini eklemeye de kaşlarını çatardım string, ancak bu cevap gerçekten de a) burada olmamalı veya b) " Tom Beech'in cevabını kullandım " thisyani bunu bir uzantısı üyesi) yapmadan - Bu yanıt ve başvurulan bir hem özdeş kısalık ve zayıf yönleri vardır. Bu noktayı belirtmeniz gerekiyorsa, diğer cevaba bir yorum yazmanız yeterlidir.
Ruben Bartelink

1

JToken.Typebaşarılı bir ayrıştırma sonrasında kullanılabilir. Bu, yukarıdaki cevaplardaki önsözlerin bir kısmını ortadan kaldırmak ve sonucun daha iyi kontrol edilmesini sağlamak için kullanılabilir. Tamamen geçersiz giriş (örneğin, "{----}".IsValidJson();yine de bir istisna atar).

    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 için referans JToken.Type: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm


0

Bu yöntem harici kitaplıklar gerektirmez

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'in cevabına dayanan bir TryParse genişletme yöntemi:

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

Kullanımı:

JToken jToken;
if (strJson.TryParse(out jToken))
{
    // work with jToken
}
else
{
    // not valid json
}

0

Bunu kullanıyorum:

  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;
     }
  }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.