如何在 JSON .NET 上对 属性 名称强制加引号
How to enforce quotes on property names on JSON .NET
我正在使用 Json.NET 解析一些 JSON 我接收到我应用程序中的端点。
我希望以下 JSON 对象无法解析,因为它的 属性 名称没有引号:
{
foo: "bar"
}
JToken.Parse()
表示有效 JSON。但是,当我使用 online parser 时,出现以下错误
Strings should be wrapped in double quotes.
有没有办法让 JSON .NET 强制执行此规则?
Json.NET 目前没有实现对 JSON 属性 名称的严格解析。
内部JToken.Parse()
构造一个JsonTextReader
来解析一个JSON字符串,看来JsonTextReader
解析不带引号的属性名称的能力目前还不能被禁用。
当通过 JsonTextReader.Read()
遍历 JSON 文件时,方法 JsonTextReader.ParseProperty()
用于解析 属性 名称:
Newtonsoft.Json.JsonTextReader.ParseUnquotedProperty()
Newtonsoft.Json.JsonTextReader.ParseProperty()
Newtonsoft.Json.JsonTextReader.ParseObject()
Newtonsoft.Json.JsonTextReader.Read()
Newtonsoft.Json.Linq.JContainer.ReadTokenFrom()
并且,从 current reference source 可以看出,此方法自动处理双引号、单引号和未引号的属性:
private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;
if (firstChar == '"' || firstChar == '\'')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else if (ValidIdentifierChar(firstChar))
{
quoteChar = '[=11=]';
ShiftBufferIfNeeded();
ParseUnquotedProperty();
}
else
{
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
// REMAINDER OMITTED
如您所见,没有选项可以配置 reader 以抛出非双引号属性的异常。
作为解决方法,current Json.NET license 允许复制和修改。因此,您应该能够创建自己的 public class StricterJsonTextReader : JsonReader
,复制自 JsonTextReader
,并按如下方式修改 ParseProperty()
:
private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;
if (firstChar == '"')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else
{
// JsonReaderException.Create() is an internal static method,
// so you will need to replace this with some extension method
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
然而,这可能不是一项完全容易的工作,因为 JsonTextReader
广泛使用了 Src/Newtonsoft.Json/Utilities
目录中的实用程序。您应该预算几天时间来制作必要实用程序的最小副本。
或者,您可以创建自己的 Json.NET 版本,自己构建,然后使用它代替官方版本。无论哪种方式,请务必从您要使用的版本中分叉源代码:
作为创建自己的解析器的替代方法,您可以使用 JsonReaderWriterFactory.CreateJsonReader()
预处理 JSON 以确保严格遵守 JSON标准:
public static class JsonExtensions
{
public static JToken StrictParse(string json)
{
try
{
// Throw an exception if the json string is not in strict compliance with the JSON standard
// by tokenizing it with the JSON reader used by DataContractJsonSerializer:
using (var stream = GenerateStreamFromString(json))
using (var reader = System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(stream, System.Xml.XmlDictionaryReaderQuotas.Max))
{
while (reader.Read())
{
}
}
}
catch (Exception ex)
{
// Wrap the XmlException in a JsonReaderException
throw new JsonReaderException("Invalid JSON", ex);
}
// Then actually parse with Json.NET
return JToken.Parse(json);
}
static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
}
(您需要为您的框架添加对适当的 .Net 程序集的引用。)
性能会更差,因为您将有效地解析您的 JSON 两次,但实现工作是微不足道的。
奇怪的是,我无法使用 JavaScriptSerializer
检查严格的 JSON 合规性,因为它也接受不带引号的 属性 名称!
// The following does not throw an exception:
new System.Web.Script.Serialization.JavaScriptSerializer().DeserializeObject("{foo : 'bar'}")
相关链接:
Disable Support for Reading (Invalid JSON) Single Quote Strings 答案是创建您自己的 JsonReader
.
Unquoted json property name没有答案。
Issue #646: Support "strict mode" for RFC7159 parsing which was closed by JamesNK。讨论线程列举了 JsonTextReader
扩展 JSON 标准的各种方式,以及 Newtonsoft 尚未实施严格解析器的一些原因。
即使问题已关闭,您当然可以添加评论以请求严格的解析选项。当然,这似乎是他们应该提供的东西。
我正在使用 Json.NET 解析一些 JSON 我接收到我应用程序中的端点。
我希望以下 JSON 对象无法解析,因为它的 属性 名称没有引号:
{
foo: "bar"
}
JToken.Parse()
表示有效 JSON。但是,当我使用 online parser 时,出现以下错误
Strings should be wrapped in double quotes.
有没有办法让 JSON .NET 强制执行此规则?
Json.NET 目前没有实现对 JSON 属性 名称的严格解析。
内部JToken.Parse()
构造一个JsonTextReader
来解析一个JSON字符串,看来JsonTextReader
解析不带引号的属性名称的能力目前还不能被禁用。
当通过 JsonTextReader.Read()
遍历 JSON 文件时,方法 JsonTextReader.ParseProperty()
用于解析 属性 名称:
Newtonsoft.Json.JsonTextReader.ParseUnquotedProperty()
Newtonsoft.Json.JsonTextReader.ParseProperty()
Newtonsoft.Json.JsonTextReader.ParseObject()
Newtonsoft.Json.JsonTextReader.Read()
Newtonsoft.Json.Linq.JContainer.ReadTokenFrom()
并且,从 current reference source 可以看出,此方法自动处理双引号、单引号和未引号的属性:
private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;
if (firstChar == '"' || firstChar == '\'')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else if (ValidIdentifierChar(firstChar))
{
quoteChar = '[=11=]';
ShiftBufferIfNeeded();
ParseUnquotedProperty();
}
else
{
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
// REMAINDER OMITTED
如您所见,没有选项可以配置 reader 以抛出非双引号属性的异常。
作为解决方法,current Json.NET license 允许复制和修改。因此,您应该能够创建自己的 public class StricterJsonTextReader : JsonReader
,复制自 JsonTextReader
,并按如下方式修改 ParseProperty()
:
private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;
if (firstChar == '"')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else
{
// JsonReaderException.Create() is an internal static method,
// so you will need to replace this with some extension method
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
然而,这可能不是一项完全容易的工作,因为 JsonTextReader
广泛使用了 Src/Newtonsoft.Json/Utilities
目录中的实用程序。您应该预算几天时间来制作必要实用程序的最小副本。
或者,您可以创建自己的 Json.NET 版本,自己构建,然后使用它代替官方版本。无论哪种方式,请务必从您要使用的版本中分叉源代码:
作为创建自己的解析器的替代方法,您可以使用 JsonReaderWriterFactory.CreateJsonReader()
预处理 JSON 以确保严格遵守 JSON标准:
public static class JsonExtensions
{
public static JToken StrictParse(string json)
{
try
{
// Throw an exception if the json string is not in strict compliance with the JSON standard
// by tokenizing it with the JSON reader used by DataContractJsonSerializer:
using (var stream = GenerateStreamFromString(json))
using (var reader = System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(stream, System.Xml.XmlDictionaryReaderQuotas.Max))
{
while (reader.Read())
{
}
}
}
catch (Exception ex)
{
// Wrap the XmlException in a JsonReaderException
throw new JsonReaderException("Invalid JSON", ex);
}
// Then actually parse with Json.NET
return JToken.Parse(json);
}
static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
}
(您需要为您的框架添加对适当的 .Net 程序集的引用。)
性能会更差,因为您将有效地解析您的 JSON 两次,但实现工作是微不足道的。
奇怪的是,我无法使用 JavaScriptSerializer
检查严格的 JSON 合规性,因为它也接受不带引号的 属性 名称!
// The following does not throw an exception:
new System.Web.Script.Serialization.JavaScriptSerializer().DeserializeObject("{foo : 'bar'}")
相关链接:
Disable Support for Reading (Invalid JSON) Single Quote Strings 答案是创建您自己的
JsonReader
.Unquoted json property name没有答案。
Issue #646: Support "strict mode" for RFC7159 parsing which was closed by JamesNK。讨论线程列举了
JsonTextReader
扩展 JSON 标准的各种方式,以及 Newtonsoft 尚未实施严格解析器的一些原因。即使问题已关闭,您当然可以添加评论以请求严格的解析选项。当然,这似乎是他们应该提供的东西。