栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

是否可以在属性中指定路径,以将类中的属性映射到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



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/398962.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号