是否可以在属性中指定路径,以将类中的属性映射到JSON中的子属性?

是否可以在属性中指定路径,以将类中的属性映射到JSON中的子属性?,第1张

是否可以在属性中指定路径,以将类中的属性映射到JSON中的子属性?

好吧,如果您只需要一个额外的属性,一种简单的方法是将JSON解析为

JObject
,使用
ToObject()
从中填充类
JObject
,然后再使用
SelectToken()
来引入额外的属性。

因此,假设您的课程如下所示:

class Person{    [JsonProperty("name")]    public string Name { get; set; }    [JsonProperty("age")]    public string Age { get; set; }    public string ProfilePicture { get; set; }}

您可以这样做:

string json = @"{    ""name"" : ""Joe Shmoe"",    ""age"" : 26,    ""picture"":    {        ""id"": 123456,        ""data"":        { ""type"": ""jpg"", ""url"": ""http://www.someplace.com/mypicture.jpg""        }    }}";JObject jo = JObject.Parse(json);Person p = jo.ToObject<Person>();p.ProfilePicture = (string)jo.SelectToken("picture.data.url");

小提琴:https :
//dotnetfiddle.net/7gnJCK


如果您希望使用更高级的解决方案,则可以进行自定义,

JsonConverter
以使
JsonProperty
属性表现出您所描述的行为。转换器将需要在类级别上运行,并结合使用上述技术和某些技术来填充所有属性。这是代码中的样子:

class JsonPathConverter : JsonConverter{    public override object ReadJson(JsonReader reader, Type objectType,    object existingValue, JsonSerializer serializer)    {        JObject jo = JObject.Load(reader);        object targetObj = Activator.CreateInstance(objectType);        foreach (PropertyInfo prop in objectType.GetProperties()    .Where(p => p.CanRead && p.CanWrite))        { JsonPropertyAttribute att = prop.GetCustomAttributes(true).OfType<JsonPropertyAttribute>().FirstOrDefault(); string jsonPath = (att != null ? att.PropertyName : prop.Name); JToken token = jo.SelectToken(jsonPath); if (token != null && token.Type != JTokenType.Null) {     object value = token.ToObject(prop.PropertyType, serializer);     prop.SetValue(targetObj, value, null); }        }        return targetObj;    }    public override bool CanConvert(Type objectType)    {        // CanConvert is not called when [JsonConverter] attribute is used        return false;    }    public override bool CanWrite    {        get { return false; }    }    public override void WriteJson(JsonWriter writer, object value,  JsonSerializer serializer)    {        throw new NotImplementedException();    }}

为了演示,我们假设JSON现在如下所示:

{  "name": "Joe Shmoe",  "age": 26,  "picture": {    "id": 123456,    "data": {      "type": "jpg",      "url": "http://www.someplace.com/mypicture.jpg"    }  },  "favorites": {    "movie": {      "title": "The Godfather",      "starring": "Marlon Brando",      "year": 1972    },    "color": "purple"  }}

…除了您之前的信息外,您还对该人最喜欢的电影(标题和年份)和最喜欢的颜色感兴趣。您将首先用

[JsonConverter]
属性标记目标类,以将其与定制转换器关联,然后
[JsonProperty]
在每个属性上使用属性,并指定所需的属性路径(区分大小写)作为名称。目标属性也不必是原语-
您可以像我在此处使用的那样使用子类
Movie
(请注意,不需要中间
Favorites
类)。

[JsonConverter(typeof(JsonPathConverter))]class Person{    [JsonProperty("name")]    public string Name { get; set; }    [JsonProperty("age")]    public int Age { get; set; }    [JsonProperty("picture.data.url")]    public string ProfilePicture { get; set; }    [JsonProperty("favorites.movie")]    public Movie FavoriteMovie { get; set; }    [JsonProperty("favorites.color")]    public string FavoriteColor { get; set; }}// Don't need to mark up these properties because they are covered by the // property paths in the Person classclass Movie{    public string Title { get; set; }    public int Year { get; set; }}

有了所有属性,您就可以照常反序列化了,它应该“正常工作”:

Person p = JsonConvert.DeserializeObject<Person>(json);

小提琴:https://dotnetfiddle.net/Ljw32O



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5005595.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存