如何使用 Newtonsoft 协定解析程序重命名和移动序列化对象的属性



我正在使用Newtonsoft来序列化和反序列化对象。以下是我的数据结构示例:

[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class BaseSerializer
{
[JsonProperty("players")] public IList<PlayersSerializer>? Players { get; set; }
}
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class PlayersSerializer
{
[JsonProperty("player1")] public PlayerSerializer? Player1{ get; set; }

[JsonProperty("otherProp")] public string? OtherProp { get; set; }
}
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class PlayerSerializer
{
[JsonProperty("name")] public string? Name{ get; set; }
}

如果我传入这个JSON:

{
"players": [
{
"player1": {
"name": "Robert Bobbert"
},
"otherProp": "Tasty"
}
]
}

收件人:

var test = JsonConvert.DeserializeObject<BaseSerializer>(json);

然后定义这个自定义ContractResolver来重命名属性:

public class MyCustomContractResolver: DefaultContractResolver
{
public static readonly MyCustomContractResolverInstance = new();
private readonly Dictionary<Type, Dictionary<string, string>> _propertyNameConverter = new()
{
{
typeof(PlayerSerializer), new Dictionary<string, string>
{
{ "name", "player1Name" },
}
},
};
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (_propertyNameConverter.ContainsKey(property.DeclaringType) &&
_propertyNameConverter[property.DeclaringType].ContainsKey(property.PropertyName))
{
property.PropertyName = _propertyNameConverter[property.DeclaringType][property.PropertyName];
}
return property;
}
}

我用";name";重命名为";播放器1名称";运行此代码时:

Console.Write(JToken.Parse(JsonConvert.SerializeObject(test, new JsonSerializerSettings { ContractResolver = MyCustomContractResolver.Instance})));
{
"players": [
{
"player1": {
"player1Name": "Robert Bobbert"
},
"otherProp": "Tasty"
}
]
}

现在的问题是;播放器1名称";为了这个例子,直接在根下(我希望这是通用的,因为在某些情况下,我可能希望它在"播放器"或其他地方(。这意味着我想要的输出是:

{
"player1Name": "Robert Bobbert",
"players": {
"otherProp": "Tasty"
}
}

我尝试访问父属性和/或更改"上的一些属性;属性";在ContractResolver中无效。

再举一个例子,我基本上想要另一个用户在这里要求的:Newtonsoft Json如何在不创建内部类对象的情况下将属性从内部类写入父类,但唯一的答案是使用dynamic,我不想这样做。

您可以解析json并转换为所需的结构

var jsonParsed = JObject.Parse(json);
Player player = new Player
{
Player1Name = (string)jsonParsed["players"][0]["player1"]["name"],
Players = new Players
{
OtherProp = (string)jsonParsed["players"][0]["otherProp"]
}
};
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Player
{
[JsonProperty("player1Name")]
public string Player1Name { get; set; }
[JsonProperty("players")]
public Players Players { get; set; }
}
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public partial class Players
{
[JsonProperty("otherProp")]
public string OtherProp { get; set; }
}

或者,如果你有几个属性,你可以使用字典,而不仅仅是OtherDrop

var playerName = (string)jsonParsed["players"][0]["player1"]["name"];
((JObject)jsonParsed["players"][0]).Properties()
.Where(x => x.Name == "player1").First().Remove();
Player player = new Player
{
Player1Name = playerName,
Players = jsonParsed["players"][0].ToObject<Dictionary<string, object>>()
};
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Player
{
[JsonProperty("player1Name")]
public string Player1Name { get; set; }
[JsonProperty("players")]
public Dictionary<string, object> Players { get; set; }
}

相关内容

  • 没有找到相关文章

最新更新