Cara memastikan bahwa string adalah JSON yang valid menggunakan JSON.NET

147

Saya punya string mentah. Saya hanya ingin memvalidasi apakah string itu JSON valid atau tidak. Saya menggunakan JSON.NET.

pengguna960567
sumber

Jawaban:

207

Melalui Kode:

Taruhan terbaik Anda adalah menggunakan parse di dalam a try-catchdan menangkap pengecualian jika parsing gagal. (Saya tidak mengetahui TryParsemetode apa pun ) .

(Menggunakan JSON.Net)

Cara paling sederhana adalah Parsemenggunakan string JToken.Parse, dan juga untuk memeriksa apakah string dimulai dengan {atau [dan diakhiri dengan }atau ]masing - masing (ditambahkan dari jawaban ini ) :

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

Alasan untuk menambahkan cek untuk {atau [lain-lain didasarkan pada fakta yang JToken.Parseakan menguraikan nilai-nilai seperti "1234"atau "'a string'"sebagai token yang valid. Pilihan lain bisa menggunakan keduanya JObject.Parsedan JArray.Parsedi parsing dan melihat apakah ada di antara mereka yang berhasil, tapi saya percaya memeriksa {}dan []harus lebih mudah. (Terima kasih @RhinoDevel karena menunjukkannya )

Tanpa JSON.Net

Anda dapat memanfaatkan .Net framework 4.5 System.Json namespace , seperti:

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

(Tapi, Anda harus menginstal System.Jsonmelalui manajer paket Nuget menggunakan perintah: PM> Install-Package System.Json -Version 4.0.20126.16343pada Package Manager Console) (diambil dari sini )

Cara Non-Kode:

Biasanya, ketika ada string json kecil dan Anda mencoba untuk menemukan kesalahan dalam string json, maka saya pribadi lebih suka menggunakan alat online yang tersedia. Apa yang biasanya saya lakukan adalah:

Habib
sumber
3
Bagaimana bisa melakukan ini saat runtime. Saya tidak ingin menggunakan try catch untuk tujuan validasi
user960567
1
Anda dapat membuat Skema untuk JSON Anda dan kemudian memverifikasi terhadap skema itu, lihat: Json.NET 3.5 Beta 2 - Validasi skema JSON
Habib
1
Adakah cara untuk melakukannya tanpa blok coba? Saya tidak menggunakan blok percobaan kecuali jika saya berurusan dengan yang tidak dikenal. Saya mencari sesuatu seperti JsonConvert.TryDeserializeObject. Hasil tangkapan operasional hanya kode buruk.
Jordan
1
Menggunakan JSON.Net: Hal ini tidak membuang pengecualian: JToken.Parse("1234")! Sebaiknya periksa dulu, apakah string dimulai dengan [atau {. Alternatif lain adalah penggunaan JObject.Parse()dan JArray.Parse().
RhinoDevel
1
JToken.Parse("{a:1}")tidak tidak membuang pengecualian meskipun ini adalah JSON tidak valid - aharus dikutip ( stackoverflow.com/q/949449/3116322 )
Ande
31

Gunakan JContainer.Parse(str)metode untuk memeriksa apakah str adalah Json yang valid. Jika ini melempar pengecualian maka itu bukan Json yang valid.

JObject.Parse- Dapat digunakan untuk memeriksa apakah string adalah objek Json yang valid
JArray.Parse- Dapat digunakan untuk memeriksa apakah string tersebut merupakan Json Array yang valid
JContainer.Parse- Dapat digunakan untuk memeriksa kedua objek Json & Array

Senthilkumar Viswanathan
sumber
17
Alih-alih JContainer itu lebih valid untuk menggunakan tipe JToken karena metode Parse () dideklarasikan pada level ini
Denis The Menace
6
Saya berasumsi bahwa Anda berbicara tentang JSON.Net: JContainer tidak berfungsi seperti itu, karena tidak akan memberikan pengecualian dalam semua kasus yang diinginkan. Contoh: JContainer.Parse("1234");.
RhinoDevel
Jawaban salah, JContainer.Parse mengerjakan apa saja
Toolkit
19

Berdasarkan jawaban Habib, Anda dapat menulis metode ekstensi:

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

Yang kemudian bisa digunakan seperti ini:

if(stringObject.ValidateJSON())
{
    // Valid JSON!
}
Tom Beech
sumber
1
JToken.Parse(s);kembali truebahkan jikaJToken.Parse(123);
Jadikan Makeluv
2
Kembali trueuntuk yang tidak valid ini JSON:{A:{"B": 1}}
Mehdi Dehghani
Metode ekstensi yang bagus untuk dimiliki :) Meskipun mungkin akan lebih baik dinamai "IsValidJson".
Mladen B.
11

Hanya untuk menambahkan sesuatu ke jawaban @ Habib, Anda juga dapat memeriksa apakah JSON yang diberikan adalah dari tipe yang valid:

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

Saya menemukan bahwa JToken.Parse salah mem-parsing JSON yang tidak valid seperti berikut ini:

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

Rekatkan string JSON ke http://jsonlint.com/ - tidak valid.

Jadi saya menggunakan:

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;
}
Andrew Roberts
sumber
Itu bukan String JSON yang tidak valid ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf di sini adalah dokumentasi dari JSON Standard ECMA dan di bawah Point 5 JSON Values ​​Anda dapat melihat suatu nilai dapat mengambil nol sebagai nilai . Jadi itu hanya bug di jsonlint interpreter
Dominik Lemberger
4
Dominik, nilai JSON menurut pembacaan saya terhadap spek yang Anda tautkan harus memiliki beberapa token yang valid, dengan teks nol literal yang mewakili nilai nol. Nilai yang valid adalah "objek, array, angka, string, true, false, atau null" sesuai dengan spesifikasi yang Anda referensikan. AFAICS tidak ada nilai yang valid tanpa token nilai.
Kirtlander
Sepertinya ini akan baik-baik saja dengan JSON tidak valid yang terlihat seperti ini{ name : "l am invalid JSON" }
Jon49
2

⚠️ Opsi Alternatif Tidak Menggunakan JSON.Net ⚠️

Untuk .Net Core / .Net 5 ( dalam pratinjau saat tulisan ini dibuat ) seseorang juga dapat menggunakan System.Text.Jsonnamespace dan parse menggunakan JsonDocument. Contoh adalah metode ekstensi berdasarkan operasi namespace:

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

    return false;
}
GamegaMan
sumber
1

Mengenai jawaban Tom Beech; Saya datang dengan yang berikut ini sebagai gantinya:

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

Dengan penggunaan berikut ini:

if (ValidateJSON(strMsg))
{
    var newGroup = DeserializeGroup(strMsg);
}
HappyCoding
sumber
3
Ini bukan novel - Anda membuat metode ekstensi bukan metode ekstensi. Jawaban Tom Beech sudah dapat mencapai apa yang Anda butuhkan (Secara umum, saya juga tidak suka menambahkan metode ekstensi semacam ini string, tetapi jawaban ini benar-benar harus a) tidak berada di sini atau b) mengatakan "Saya menggunakan jawaban Tom Beech " tanpa the this, yaitu tanpa menjadikannya anggota ekstensi) - baik jawaban ini maupun yang direferensikan memiliki keringkasan dan kelemahan yang identik. Jika Anda harus membuat poin ini, cukup beri komentar pada jawaban lainnya.
Ruben Bartelink
1

JToken.Typetersedia setelah penguraian yang sukses. Ini dapat digunakan untuk menghilangkan beberapa mukadimah dalam jawaban di atas dan memberikan wawasan untuk kontrol hasil yang lebih baik. Masukan yang sepenuhnya tidak valid (mis. "{----}".IsValidJson();Masih akan memberikan pengecualian).

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

Referensi Json.Net untuk JToken.Type: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm

Randy Larson
sumber
0

Metode ini tidak memerlukan perpustakaan eksternal

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

Berikut adalah metode ekstensi TryParse berdasarkan jawaban Habib:

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

Pemakaian:

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

Saya menggunakan ini:

  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;
     }
  }
Yousha Aleayoub
sumber