如何在 Newtonsoft.JsonConvert.SerializeObject 期间注入 JSON $schema 值
How to inject the JSON $schema value during Newtonsoft.JsonConvert.SerializeObject
我使用以下方法为我的 C# 代码创建了一个 JSON 模式:
// Create JSON schema
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(ConfigFileJsonSchema));
schema.Title = "PlexCleaner Schema";
schema.Description = "PlexCleaner config file JSON schema";
schema.SchemaVersion = new Uri("http://json-schema.org/draft-06/schema");
schema.Id = new Uri("https://raw.githubusercontent.com/ptr727/PlexCleaner/main/PlexCleaner.schema.json");
Console.WriteLine(schema);
每当我从我的代码创建 JSON 输出时,我想添加对此方案的引用:
private static string ToJson(ConfigFileJsonSchema settings)
{
return JsonConvert.SerializeObject(settings, Settings);
}
private static readonly JsonSerializerSettings Settings = new()
{
Formatting = Formatting.Indented,
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
NullValueHandling = NullValueHandling.Ignore,
// We expect containers to be cleared before deserializing
// Make sure that collections are not read-only (get; set;) else deserialized values will be appended
//
ObjectCreationHandling = ObjectCreationHandling.Replace
// TODO: Add TraceWriter to log to Serilog
};
如何以编程方式将 $schema
URI 添加到创建的 JSON,这并不意味着即时创建模式,而是像这样:
public class ConfigFileJsonSchemaBase
{
// Schema reference
[JsonProperty(PropertyName = "$schema", Order = -2)]
public string Schema { get; } = "https://raw.githubusercontent.com/ptr727/PlexCleaner/main/PlexCleaner.schema.json";
// Default to 0 if no value specified, and always write the version first
[DefaultValue(0)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate, Order = -2)]
public int SchemaVersion { get; set; } = ConfigFileJsonSchema.Version;
}
无需向 class 添加 $schema
条目。
例如。相当于:
schema.SchemaVersion = new Uri("http://json-schema.org/draft-06/schema");
还有一个类似的未回答问题:json serialization to refer schema
您可以使用 JsonConverter:
public class SchemaJsonConverter : JsonConverter
{
private readonly string _schemaUrl;
private readonly Type[] _types;
public SchemaJsonConverter(string schemaUrl, params Type[] types)
{
this._schemaUrl = schemaUrl;
this._types = types;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else
{
var o = (JObject)t;
o.AddFirst(new JProperty("$Schema", this._schemaUrl));
o.WriteTo(writer);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return this._types.Any(t => t == objectType);
}
}
您需要类型来检查受转换器影响的类型和架构 url 以将其注入您的 JSON。该转换器允许您对序列化过程进行精细控制。
我用一个简单的class来测试转换器:
public class Something
{
public int Integer { get; set; }
public string Text { get; set; }
}
以及 运行 示例的方法:
public static void Test()
{
var something = new Something
{
Integer = 37,
Text = "A text"
};
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
NullValueHandling = NullValueHandling.Ignore,
// We expect containers to be cleared before deserializing
// Make sure that collections are not read-only (get; set;) else deserialized values will be appended
//
ObjectCreationHandling = ObjectCreationHandling.Replace
// TODO: Add TraceWriter to log to Serilog
};
var schemaUrl = "http://json-schema.org/draft-06/schema";
settings.Converters.Add(new SchemaJsonConverter(schemaUrl, something.GetType()));
var json = JsonConvert.SerializeObject(something, settings);
Console.WriteLine(json);
}
输出:
{
"$Schema": "http://json-schema.org/draft-06/schema",
"Integer": 37,
"Text": "A text"
}
更新
序列化的静态方法:
public static string SerializeJson(object obj, JsonSerializerSettings settings, string schemaUrl = null)
{
if (!string.IsNullOrEmpty(schemaUrl))
{
settings.Converters.Add(new SchemaJsonConverter(schemaUrl, obj.GetType()));
}
return JsonConvert.SerializeObject(obj, settings);
}
用法:
var json = SerializeJson(something, settings, schemaUrl);
我使用以下方法为我的 C# 代码创建了一个 JSON 模式:
// Create JSON schema
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(ConfigFileJsonSchema));
schema.Title = "PlexCleaner Schema";
schema.Description = "PlexCleaner config file JSON schema";
schema.SchemaVersion = new Uri("http://json-schema.org/draft-06/schema");
schema.Id = new Uri("https://raw.githubusercontent.com/ptr727/PlexCleaner/main/PlexCleaner.schema.json");
Console.WriteLine(schema);
每当我从我的代码创建 JSON 输出时,我想添加对此方案的引用:
private static string ToJson(ConfigFileJsonSchema settings)
{
return JsonConvert.SerializeObject(settings, Settings);
}
private static readonly JsonSerializerSettings Settings = new()
{
Formatting = Formatting.Indented,
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
NullValueHandling = NullValueHandling.Ignore,
// We expect containers to be cleared before deserializing
// Make sure that collections are not read-only (get; set;) else deserialized values will be appended
//
ObjectCreationHandling = ObjectCreationHandling.Replace
// TODO: Add TraceWriter to log to Serilog
};
如何以编程方式将 $schema
URI 添加到创建的 JSON,这并不意味着即时创建模式,而是像这样:
public class ConfigFileJsonSchemaBase
{
// Schema reference
[JsonProperty(PropertyName = "$schema", Order = -2)]
public string Schema { get; } = "https://raw.githubusercontent.com/ptr727/PlexCleaner/main/PlexCleaner.schema.json";
// Default to 0 if no value specified, and always write the version first
[DefaultValue(0)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate, Order = -2)]
public int SchemaVersion { get; set; } = ConfigFileJsonSchema.Version;
}
无需向 class 添加 $schema
条目。
例如。相当于:
schema.SchemaVersion = new Uri("http://json-schema.org/draft-06/schema");
还有一个类似的未回答问题:json serialization to refer schema
您可以使用 JsonConverter:
public class SchemaJsonConverter : JsonConverter
{
private readonly string _schemaUrl;
private readonly Type[] _types;
public SchemaJsonConverter(string schemaUrl, params Type[] types)
{
this._schemaUrl = schemaUrl;
this._types = types;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken t = JToken.FromObject(value);
if (t.Type != JTokenType.Object)
{
t.WriteTo(writer);
}
else
{
var o = (JObject)t;
o.AddFirst(new JProperty("$Schema", this._schemaUrl));
o.WriteTo(writer);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return this._types.Any(t => t == objectType);
}
}
您需要类型来检查受转换器影响的类型和架构 url 以将其注入您的 JSON。该转换器允许您对序列化过程进行精细控制。
我用一个简单的class来测试转换器:
public class Something
{
public int Integer { get; set; }
public string Text { get; set; }
}
以及 运行 示例的方法:
public static void Test()
{
var something = new Something
{
Integer = 37,
Text = "A text"
};
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
NullValueHandling = NullValueHandling.Ignore,
// We expect containers to be cleared before deserializing
// Make sure that collections are not read-only (get; set;) else deserialized values will be appended
//
ObjectCreationHandling = ObjectCreationHandling.Replace
// TODO: Add TraceWriter to log to Serilog
};
var schemaUrl = "http://json-schema.org/draft-06/schema";
settings.Converters.Add(new SchemaJsonConverter(schemaUrl, something.GetType()));
var json = JsonConvert.SerializeObject(something, settings);
Console.WriteLine(json);
}
输出:
{
"$Schema": "http://json-schema.org/draft-06/schema",
"Integer": 37,
"Text": "A text"
}
更新
序列化的静态方法:
public static string SerializeJson(object obj, JsonSerializerSettings settings, string schemaUrl = null)
{
if (!string.IsNullOrEmpty(schemaUrl))
{
settings.Converters.Add(new SchemaJsonConverter(schemaUrl, obj.GetType()));
}
return JsonConvert.SerializeObject(obj, settings);
}
用法:
var json = SerializeJson(something, settings, schemaUrl);