通过JsonConstructor
使用特定.ctor对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; }
}
这只是Json.Net
如何调用构造函数的“限制”,还是我缺少的东西。
仅供参考:我是通过Rosyln生成所有这些代码的代码,我不打算为此为每种类型生成JsonConverter
...
答案 0 :(得分:10)
当Json.NET调用参数化构造函数时,它会按名称将JSON属性与构造函数参数匹配。但是,对于也与类型成员对应的JSON属性,它使用哪个名称 - 成员名称或JsonPropertyAttribute.PropertyName
指定的覆盖类型成员名称?
您似乎希望它与两者匹配,因为您的参数命名约定不一致:
构造函数参数production_countries
匹配重写的属性名称:
[JsonProperty("production_countries")]
public IList<IProductionCountry> ProductionCountries { get; set; }
构造函数参数IList<SpokenLanguage> SpokenLanguages
匹配反射的名称而不是重写的属性名称:
[JsonProperty("spoken_languages")]
public IList<ISpokenLanguage> SpokenLanguages { get; set; }
IList<SysType> SysTypes
都不匹配(这是问题中的拼写错误吗?)
然而,重要的是JSON文件本身的属性名称 和构造函数参数名称,如JsonSerializerInternalReader.ResolvePropertyAndCreatorValues()
所示。该算法的简化版本如下:
(当JSON属性与匹配时,实现变得复杂,并且开发人员期望在构造函数中设置时,应该尊重添加到成员的[JsonProperty(Required = Required.Always)]
。)
因此构造函数参数production_countries
将匹配JSON中名为"production_countries"
的值,而构造函数参数SpokenLanguages
将不匹配名为{的JSON值{1}}。
那么,如何成功反序列化您的类型?首先,您可以使用"spoken_languages"
标记构造函数参数,以覆盖反序列化期间使用的构造函数名称:
[JsonProperty(overrideName)]
其次,由于您似乎使用构造函数将包含接口的集合中的项目反序列化为具体对象,因此您可以考虑使用基于CustomCreationConverter
的单个通用转换器作为ItemConverter
:
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();
}
Example fiddle显示两个选项。