我在这里发现了同样的问题...
Deserializing nested JSON structure to a flattened class with Json.NET using annotations
...但没有正确的答案。 最好的建议之一是将嵌套对象包装在一个新类中,但这种方法引入了另一个问题:乐高名称。在我的示例中,此类的最逻辑名称与父类和当然不可能。我的例子很简单,我只是想消除父类中的“语言”属性。有人可以帮我做吗?
using Newtonsoft.Json;
public partial class NamedType
{
public string Name { get; set; }
}
public class Proficiency
{
public string Level { get; set; }
public string Name { get; set; }
}
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
//public Language Language { get; set; } //Compiler error
//public Language Value { get; set; } //Not correct
//public NamedType Language { get; set; } //Compiler error
//public NamedType Value { get; set; } //Ugly, isn't?
public Proficiency Proficiency { get; set; }
}
List<Language> languageList = JsonConvert.DeserializeObject<List<Language>>(json);
json 示例:
{
"languages": [
{
"id": 1,
"language": { "name": "Spanish" },
"proficiency": {
"level": "native_or_bilingual",
"name": "Native or bilingual proficiency"
}
},
{
"id": 2,
"language": { "name": "English" },
"proficiency": {
"level": "full_professional",
"name": "Full professional proficiency"
}
},
{
"id": 3,
"language": { "name": "Japanese" },
"proficiency": {
"level": "elementary",
"name": "Elementary proficiency"
}
}
]
}
最佳答案
如果 JSON 属性名称与 C# 命名约定冲突,您可以在序列化期间使用 DataMember
或 JsonProperty
注释来替换不同的名称。
例如,以下代码适用于 DataContractJsonSerializer
和 Json.NET:
[DataContract]
public class Language
{
[DataContract]
class NamedType
{
[DataMember]
public string name { get; set; }
}
[DataContract]
class ProficiencyType
{
[DataMember]
public string level { get; set; }
[DataMember]
public string name { get; set; }
}
[DataMember(Name="id")]
public int Id { get; set; }
[IgnoreDataMember] // Do not serialize this property
public string Name { get; set; }
[IgnoreDataMember]
public string ProficiencyLevel { get; set; }
[IgnoreDataMember]
public string ProficiencyName { get; set; }
[DataMember(Name="language")] // serialize this nested class property with name "language"
[JsonProperty(ObjectCreationHandling=ObjectCreationHandling.Replace)] // When deserializing, always create a fresh instance instead of reusing the proxy class.
NamedType LanguageName
{
get
{
return new NamedType { name = Name };
}
set
{
Name = (value == null ? null : value.name);
}
}
[DataMember(Name = "proficiency")]
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
ProficiencyType Proficiency
{
get
{
return new ProficiencyType { level = ProficiencyLevel, name = ProficiencyName };
}
set
{
ProficiencyLevel = (value == null ? null : value.level);
ProficiencyName = (value == null ? null : value.name);
}
}
}
如果您发现 DataContract
属性的选择加入性质很麻烦,并且更喜欢使用 Json.NET 特定的属性,那么以下内容是等效的:
public class Language
{
class NamedType
{
public string name { get; set; }
}
class ProficiencyType
{
public string level { get; set; }
public string name { get; set; }
}
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[JsonIgnore]
public string Name { get; set; }
[JsonIgnore]
public string ProficiencyLevel { get; set; }
[JsonIgnore]
public string ProficiencyName { get; set; }
[JsonProperty(PropertyName = "language", ObjectCreationHandling = ObjectCreationHandling.Replace)]
NamedType LanguageName
{
get
{
return new NamedType { name = Name };
}
set
{
Name = (value == null ? null : value.name);
}
}
[JsonProperty(PropertyName = "proficiency", ObjectCreationHandling = ObjectCreationHandling.Replace)]
ProficiencyType Proficiency
{
get
{
return new ProficiencyType { level = ProficiencyLevel, name = ProficiencyName };
}
set
{
ProficiencyLevel = (value == null ? null : value.level);
ProficiencyName = (value == null ? null : value.name);
}
}
}
关于json - 将 JSON 反序列化为扁平化类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30222921/