我在一个项目中有一个json模式,并希望添加构建步骤以从它们生成类,这些模式包含一个对象和字符串数组,简化示例如下:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "testSchema",
"type": "object",
"properties": {
"array": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
]
}
}
}
}
我正在使用NJsonSchema从此架构生成C#代码。结果我得到以下输出:
//----------------------
// <auto-generated>
// Generated using the NJsonSchema v8.32.6319.16936 (http://NJsonSchema.org)
// </auto-generated>
//----------------------
namespace TestSchema
{
#pragma warning disable // Disable all warnings
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "8.32.6319.16936")]
public partial class TestSchema : System.ComponentModel.INotifyPropertyChanged
{
private System.Collections.ObjectModel.ObservableCollection<Anonymous> _array = new System.Collections.ObjectModel.ObservableCollection<Anonymous>();
[Newtonsoft.Json.JsonProperty("array", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.Collections.ObjectModel.ObservableCollection<Anonymous> Array
{
get { return _array; }
set
{
if (_array != value)
{
_array = value;
RaisePropertyChanged();
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
public static TestSchema FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<TestSchema>(data);
}
protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "8.32.6319.16936")]
public partial class Anonymous : System.ComponentModel.INotifyPropertyChanged
{
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
public static Anonymous FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<Anonymous>(data);
}
protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
结果我有了这个奇怪的Anonymous
类,如果我尝试反序列化下面的json文件,我会收到错误:string
无法转换为Anonymous
。要反序列化,我使用以下生成的方法:
TestSchema.FromJson
是否可以调整代码生成,从而得到object
的集合,并获得具有正确类型的反序列化对象?
{
"array": [
"stringItem1",
{
"name": "complexObj1"
}
]
}
答案 0 :(得分:1)
最后,我实现了我所需要的。
我们的想法是将自定义CSharpTypeResolver
传递给CSharpGenerator
:
新的CSharpGenerator(jsonSchema4,设置,新的CustomCSharpTypeResolver(设置,jsonSchema4),null);
NJsonSchema
作者认为它不是故意的。
在CustomCSharpTypeResolver
中,我重写Resolve
方法以添加以下行为:
if (schema.AnyOf.Count > 0)
return "object";
作为简化示例的结果,我有以下模型:
//----------------------
// <auto-generated>
// Generated using the NJsonSchema v8.32.6319.16936 (http://NJsonSchema.org)
// </auto-generated>
//----------------------
namespace JsonSchemaClassGenerator.TestSchema
{
#pragma warning disable // Disable all warnings
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "8.32.6319.16936")]
public partial class TestSchema : System.ComponentModel.INotifyPropertyChanged
{
private System.Collections.ObjectModel.ObservableCollection<object> _array = new System.Collections.ObjectModel.ObservableCollection<object>();
[Newtonsoft.Json.JsonProperty("array", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.Collections.ObjectModel.ObservableCollection<object> Array
{
get { return _array; }
set
{
if (_array != value)
{
_array = value;
RaisePropertyChanged();
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
public static TestSchema FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<TestSchema>(data);
}
protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "8.32.6319.16936")]
public partial class Object : System.ComponentModel.INotifyPropertyChanged
{
private string _name;
[Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged();
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
public static Object FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<Object>(data);
}
protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
反序列化工作正常。我可以按照自己的意愿投射物体。只有一个问题:对象被保存为JObject
个实例,因此我需要实现explicit
或implicit
运算符将其转换为生成的模型。
namespace JsonSchemaClassGenerator.TestSchema
{
public partial class Object
{
public static implicit operator Object(JObject json)
{
return FromJson(json.ToString());
}
}
}
之后可以将JObject
转换为生成的模型(Object
不是System.Object
它只是使用这样的名称生成的):
Object a = config.Entries[1] as JObject;
这是我发现的最简单的解决方案。我认为也可以实现自定义CSharpTypeResolver
以获得更安全的类型。但不确定我是否会尝试,因为对我而言,看起来最好先使NJsonSchema
更灵活。