首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Json.Net反序列化JSON,用SubTypes反序列化Xamarin?

如何用Json.Net反序列化JSON,用SubTypes反序列化Xamarin?
EN

Stack Overflow用户
提问于 2018-01-24 01:05:12
回答 1查看 709关注 0票数 2

我正在尝试反序列化这个json:

代码语言:javascript
复制
{
  "teaser": [{
              "id": "...",
              "type": "category",
              "url": "https:...",
            },{
              "id": "...",
              "type": "brand",
              "url": "https:...",
              "videoCount": 1,
            },{
              "id": "...",
              "type": "video",
              "url": "https:...",
              "headline": "...",
            }]
}

它有一个预告列表,其中每个预告根据其类型而不同。这些是我的对象:

代码语言:javascript
复制
public class StartPage
{
        public IList<Teaser> Teaser { get; set; }
}

public abstract class Teaser
{
        public string Id { get; set; }
        public string Url { get; set; }
}

public class Video : Teaser
{
        public string Headline { get; set; }
}

public class Brand : Teaser
{
        public int VideoCount { get; set; }
}

我是Json.NET和Xamarin的新手,还没有找到解决这个问题的方法。以前,当我使用Android Studio和Gson时,我可以通过以下方式注册sybtype:

代码语言:javascript
复制
RuntimeTypeAdapterFactory<Teaser> teaserRuntimeTypeAdapterFactory = RuntimeTypeAdapterFactory.of(
                Teaser.class, "type")
                .registerSubtype(Video.class, Teaser.TYPE_VIDEO)
                .registerSubtype(Brand.class, Teaser.TYPE_BRAND)
                .registerSubtype(Category.class, Teaser.TYPE_CATEGORY);

        return new GsonBuilder()
                .registerTypeAdapterFactory(teaserRuntimeTypeAdapterFactory);

有没有类似的方法可以用Json.NET实现我想要的东西,但我还忽略了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-24 01:40:28

您可以做的是创建自定义JsonConverter,请在下面的代码片段中找到this . net fiddle

代码语言:javascript
复制
string json ="{ 'Teaser': [{ 'id': '...', 'type': 'category', 'url': 'https:...', },{ 'id': '...', 'type': 'brand', 'url': 'https:...', 'videoCount': 1, },{ 'id': '...', 'type': 'video', 'url': 'https:...', 'headline': '...', }]}";

var list = JsonConvert.DeserializeObject<StartPage>(json);

public class BaseSpecifiedConcreteClassConverter : DefaultContractResolver
    {
        protected override JsonConverter ResolveContractConverter(Type objectType)
        {
            if (typeof(Teaser).IsAssignableFrom(objectType) && !objectType.IsAbstract)
                return null; // pretend TableSortRuleConvert is not specified (thus avoiding a stack overflow)
            return base.ResolveContractConverter(objectType);
        }
    }

public class BaseConverter : JsonConverter
    {
        static JsonSerializerSettings SpecifiedSubclassConversion = new JsonSerializerSettings() { ContractResolver = new BaseSpecifiedConcreteClassConverter() };

        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(Teaser));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jo = JObject.Load(reader);
            switch (jo["type"].Value<string>())
            {
                case "video":
                    return JsonConvert.DeserializeObject<Video>(jo.ToString(), SpecifiedSubclassConversion);
                case "brand":
                    return JsonConvert.DeserializeObject<Brand>(jo.ToString(), SpecifiedSubclassConversion);
                default:
                    throw new Exception();
            }
            throw new NotImplementedException();
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException(); // won't be called because CanWrite returns false
        }
    }

随意在switch case中创建自定义逻辑硬编码类名可能不是一个好主意,而是创建enum或类似的东西,但这就是实现这种类型的场景的方法

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48407196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档