Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用JSON.Net反序列化JSON,使用子类型反序列化Xamarin?_C#_Json.net_Subtype - Fatal编程技术网

C# 如何使用JSON.Net反序列化JSON,使用子类型反序列化Xamarin?

C# 如何使用JSON.Net反序列化JSON,使用子类型反序列化Xamarin?,c#,json.net,subtype,C#,Json.net,Subtype,我正在尝试反序列化此json: { "teaser": [{ "id": "...", "type": "category", "url": "https:...", },{ "id": "...", "type": "brand", "url": "https:...",

我正在尝试反序列化此json:

{
  "teaser": [{
              "id": "...",
              "type": "category",
              "url": "https:...",
            },{
              "id": "...",
              "type": "brand",
              "url": "https:...",
              "videoCount": 1,
            },{
              "id": "...",
              "type": "video",
              "url": "https:...",
              "headline": "...",
            }]
}
它有一个预告片列表,根据其类型,每个预告片都是不同的。 这些将是我的目标:

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; }
}
公共类起始页
{
公共IList摘要程序{get;set;}
}
公共抽象类摘要
{
公共字符串Id{get;set;}
公共字符串Url{get;set;}
}
公开课视频:预告片
{
公共字符串标题{get;set;}
}
大众级品牌:挑逗者
{
public int VideoCount{get;set;}
}
我是Json.NET和Xamarin的新手,还没有找到解决这个问题的方法。以前,当我使用Android Studio和Gson时,我可以通过以下方式注册SybType:

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);
RuntimeTypeAdapterFactory-TriserRuntimeTypeAdapterFactory=RuntimeTypeAdapterFactory.of(
striser.class,“type”)
.registerSubtype(Video.class、trister.TYPE\u Video)
.registerSubtype(Brand.class、trister.TYPE\u Brand)
.registerSubtype(Category.class、striser.TYPE\u Category);
返回新的GsonBuilder()
.registerTypeAdapterFactory(TriserRuntimeTypeAdapterFactory);

有没有一种类似的方法来实现我对Json.NET的期望,而我却忽略了这一点?

您可以做的是创建自定义
JsonConverter
请在代码段下方找到dot NET fiddle

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
        }
    }
string json=“{'striser':[{'id':'','type':'category','url':'https:',},{'id':','type','brand','url':'https:','videoCount','videoCount':1,},{'id':','type','video','url':'https:','headline','headline':'https:',}”;
var list=JsonConvert.DeserializeObject(json);
公共类BaseSpecifiedConcreteClassConverter:DefaultContractResolver
{
受保护的重写JsonConverter ResolveContractConverter(类型objectType)
{
if(typeof(trister).IsAssignableFrom(objectType)&!objectType.isastract)
return null;//未指定假装TableSortRuleConvert(从而避免堆栈溢出)
返回base.ResolveContractConverter(objectType);
}
}
公共类BaseConverter:JsonConverter
{
静态JsonSerializerSettings SpecifiedSubclassConversion=new JsonSerializerSettings(){ContractResolver=new BaseSpecifiedConcreteClassConverter()};
公共覆盖布尔CanConvert(类型objectType)
{
返回(objectType==typeof(摘要));
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
JObject jo=JObject.Load(读卡器);
开关(jo[“type”].Value())
{
案例“视频”:
返回JsonConvert.DeserializeObject(jo.ToString(),SpecifiedSubclassConversion);
案例“品牌”:
返回JsonConvert.DeserializeObject(jo.ToString(),SpecifiedSubclassConversion);
违约:
抛出新异常();
}
抛出新的NotImplementedException();
}
公共覆盖布尔可写
{
获取{return false;}
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
throw new NotImplementedException();//不会被调用,因为CanWrite返回false
}
}

请随意在
switch case
硬代码类名中创建自定义逻辑,而不是创建
enum
或类似的内容,但这就是实现此类场景的方法

您阅读过json.net文档或示例吗?阅读有关此主题的stackoverflow线程:非常感谢!那正是我要找的!必须使用System.Reflection并将ResolveContractConverter稍微重写为
typeof(trister).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo())&&!objectType.GetTypeInfo().IsaStract
但其他一切都像一个魔咒!