使用特定的.ctor via JsonConstructor进行反序列化IList<ISomeInterface>属性时,参数名称必须与原始 Json名称匹配,并且JsonProperty不使用这些属性上的映射.
SpokenLanguages参数始终为null,因为它不匹配spoken_languages,但JsonProperty它有一个映射:
public partial class AClass : ISomeBase
{
public AClass() { }
[JsonConstructor]
public AClass(IList<SysType> SysTypes, IList<ProductionCountry> production_countries, IList<SpokenLanguage> SpokenLanguages)
{
this.Genres = SysTypes?.ToList<IGenre>();
this.ProductionCountries = production_countries?.ToList<IProductionCountry>();
this.SpokenLanguages = SpokenLanguages?.ToList<ISpokenLanguage>();
}
public int Id { get; set; }
public IList<IGenre> Genres { get; set; }
[JsonProperty("production_countries")]
public IList<IProductionCountry> ProductionCountries { get; set; }
[JsonProperty("spoken_languages")]
public IList<ISpokenLanguage> SpokenLanguages { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这只是Json.Net调用构造函数的一个"限制",还是我缺少的东西.
仅供参考:我是通过Rosyln生成所有这些的代码,我不打算JsonConverter为此生成每种类型的...
dbc*_*dbc 12
当Json.NET调用参数化构造函数时,它会按名称将JSON属性与构造函数参数匹配.但是,对于也与类型成员对应的JSON属性,它使用哪个名称 - 成员名称,或者由JsonPropertyAttribute.PropertyName?指定的覆盖类型成员名称?
看起来你希望它匹配两个,因为你的论点命名约定不一致:
构造函数参数production_countries匹配重写的属性名称:
[JsonProperty("production_countries")]
public IList<IProductionCountry> ProductionCountries { get; set; }
Run Code Online (Sandbox Code Playgroud)构造函数参数IList<SpokenLanguage> SpokenLanguages匹配反射的名称而不是重写的属性名称:
[JsonProperty("spoken_languages")]
public IList<ISpokenLanguage> SpokenLanguages { get; set; }
Run Code Online (Sandbox Code Playgroud)IList<SysType> SysTypes 两者都不匹配(这是问题中的拼写错误吗?)
但是,重要的是JSON文件本身的属性名称和构造函数参数名称,如图所示JsonSerializerInternalReader.ResolvePropertyAndCreatorValues().该算法的简化版本如下:
(当JSON属性与两者兼容时,实现变得复杂,并且开发人员期望[JsonProperty(Required = Required.Always)]在构造函数中设置时应该遵守添加到成员的内容.)
因此构造函数参数production_countries将匹配"production_countries"JSON 中指定的值,而构造函数参数SpokenLanguages将与命名的JSON值不匹配"spoken_languages".
那么,如何成功反序列化您的类型?首先,您可以使用构造函数参数[JsonProperty(overrideName)]来覆盖反序列化期间使用的构造函数名称:
public partial class AClass : ISomeBase
{
public AClass() { }
[JsonConstructor]
public AClass([JsonProperty("Genres")] IList<SysType> SysTypes, IList<ProductionCountry> production_countries, [JsonProperty("spoken_languages")] IList<SpokenLanguage> SpokenLanguages)
{
this.Genres = SysTypes == null ? null : SysTypes.Cast<IGenre>().ToList();
this.ProductionCountries = production_countries == null ? null : production_countries.Cast<IProductionCountry>().ToList();
this.SpokenLanguages = SpokenLanguages == null ? null : SpokenLanguages.Cast<ISpokenLanguage>().ToList();
}
Run Code Online (Sandbox Code Playgroud)
其次,既然你似乎可以用构造反序列化包含接口,具体的对象的集合项目,你可以考虑使用基于一个通用的转换器CustomCreationConverter为ItemConverter:
public partial class AClass : ISomeBase
{
public AClass() { }
public int Id { get; set; }
[JsonProperty(ItemConverterType = typeof(CustomCreationConverter<IGenre, SysType>))]
public IList<IGenre> Genres { get; set; }
[JsonProperty("production_countries", ItemConverterType = typeof(CustomCreationConverter<IProductionCountry, ProductionCountry>))]
public IList<IProductionCountry> ProductionCountries { get; set; }
[JsonProperty("spoken_languages", ItemConverterType = typeof(CustomCreationConverter<ISpokenLanguage, SpokenLanguage>))]
public IList<ISpokenLanguage> SpokenLanguages { get; set; }
}
public class CustomCreationConverter<T, TSerialized> : CustomCreationConverter<T> where TSerialized : T, new()
{
public override T Create(Type objectType)
{
return new TSerialized();
}
}
Run Code Online (Sandbox Code Playgroud)
显示两个选项的示例小提琴.
| 归档时间: |
|
| 查看次数: |
2514 次 |
| 最近记录: |