【发布时间】:2013-02-05 08:03:53
【问题描述】:
我有一个原始字符串。我只想验证字符串是否是有效的 JSON。我正在使用 JSON.NET。
【问题讨论】:
我有一个原始字符串。我只想验证字符串是否是有效的 JSON。我正在使用 JSON.NET。
【问题讨论】:
通过代码:
最好的办法是在 try-catch 中使用 parse 并在解析失败的情况下捕获异常。 (我不知道有任何TryParse 方法)。
(使用 JSON.Net)
最简单的方法是使用JToken.Parse 到Parse 字符串,并检查字符串是否以{ 或[ 开头并分别以} 或] 结尾(添加来自answer):
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.Parse 和JArray.Parse 进行解析并查看其中是否有人成功,但我相信检查{} 和[] 应该更容易。 (谢谢@RhinoDevel for pointing 出来)
没有 JSON.Net
您可以使用 .Net framework 4.5 System.Json namespace ,例如:
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.Json,在包管理器控制台上使用命令:PM> Install-Package System.Json -Version 4.0.20126.16343)(取自 here)
非编码方式:
通常,当有一个小的 json 字符串并且您试图在 json 字符串中查找错误时,我个人更喜欢使用可用的在线工具。我通常做的是:
【讨论】:
JToken.Parse("1234")!如果字符串以[ 或{ 开头,最好先检查一下。另一种选择是使用JObject.Parse() 和JArray.Parse()。
JToken.Parse("{a:1}") not 会抛出异常,即使这是无效的 JSON - a 应该被引用 (stackoverflow.com/q/949449/3116322)
使用JContainer.Parse(str) 方法来检查str是否是一个有效的Json。如果这抛出异常,那么它不是一个有效的 Json。
JObject.Parse - 可用于检查字符串是否为有效的 Json 对象JArray.Parse - 可用于检查字符串是否为有效的 Json 数组JContainer.Parse - 可用于检查 Json 对象和数组
【讨论】:
JContainer.Parse("1234");.
1234 是有效的 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!
}
【讨论】:
JToken.Parse(s); 返回true 即使JToken.Parse(123);
JSON返回true:{A:{"B": 1}}
123 是有效的 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;
}
【讨论】:
{ name : "l am invalid JSON" }
⚠️使用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;
}
【讨论】:
JsonDocument 是一次性的。根据文档,不这样做会result in the memory not being returned to the (memory) pool, which will increase GC impact across various parts of the framework.。所以你需要在某处添加一个using。
using 的 dispose 模式将是一个好主意。
关于汤姆·比奇的回答;我想出了以下内容:
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);
}
【讨论】:
string 上添加这种扩展方法,但这个答案真的应该要么a)不在这里,要么b)说“我用过@987654321 @" 没有this,即没有使其成为扩展成员) - 这个答案和引用的答案都具有相同的简洁性和弱点。如果您必须说明这一点,只需对其他答案发表评论即可。
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://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm
【讨论】:
此方法不需要外部库
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字符串的扩展:
公共静态字符串 OnlyValidJson(此字符串 strInput) { if (string.IsNullOrWhiteSpace(strInput)) { return @"[""Json 为空""]"; } strInput = strInput.Trim(); if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || (strInput.StartsWith("[") && strInput.EndsWith("]"))) { 尝试 { 字符串 strEscape = strInput.Replace("\\n", "").Replace("\\r", "").Replace("\n", "").Replace("\r", "") ; JToken.Parse(strEscape); 返回strEscape; } 捕捉(JsonReaderException jex) { 返回@$"{{""JsonReaderException"":""{jex.Message}""}}"; } 捕捉(例外前) { Console.WriteLine(ex.ToString()); 返回@$"{{""异常"":""{ex.ToString()}""}}"; } } 别的 { return @"[""Json 不以 { 或 [.""]" 开头; } }【讨论】: