Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.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# JSONVERT反序列化抽象类数组_C#_Json.net_Abstract Class_Json Deserialization - Fatal编程技术网

C# JSONVERT反序列化抽象类数组

C# JSONVERT反序列化抽象类数组,c#,json.net,abstract-class,json-deserialization,C#,Json.net,Abstract Class,Json Deserialization,假设我有以下类结构(Building是一个抽象类): 然后,我创建了一个street对象,其中包含建筑物阵列中的几个平面: Flat f1 = new Flat { Name = "Flat 1", WhichFloor = 1 }; Flat f2 = new Flat { Name = "Flat 2", WhichFloor = 2 }; Street street = new Street { StreetName = "Street Name", Buildings

假设我有以下类结构(Building是一个抽象类):

然后,我创建了一个street对象,其中包含建筑物阵列中的几个平面:

Flat f1 = new Flat { Name = "Flat 1", WhichFloor = 1 };
Flat f2 = new Flat { Name = "Flat 2", WhichFloor = 2 };

Street street = new Street
{
    StreetName = "Street Name",
    Buildings = new[] { f1, f2 }
};
然后使用JsonConvert序列化对象:

var toJson = JsonConvert.SerializeObject(street);
现在我想将json转换回street对象:

var fromJson = JsonConvert.DeserializeObject<Street>(toJson);
var fromJson=JsonConvert.DeserializeObject(toJson);
此操作失败,出现以下错误:

“无法创建Building类型的实例。type是接口或抽象类,无法实例化。路径'Buildings[0]。WhichFloor'”


如何告诉JsonConvert类建筑应该是一组平面?

根据@Evk的共享链接,在序列化和反序列化时,您应该尝试将
TypeNameHandling
设置为
TypeNameHandling.Auto

var toJson = JsonConvert.SerializeObject(street, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});


var fromJson = JsonConvert.DeserializeObject<Street>(toJson, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});
var-toJson=JsonConvert.SerializeObject(street,Newtonsoft.Json.Formatting.Indented,new-JsonSerializerSettings
{
TypeNameHandling=TypeNameHandling.Auto
});
var fromJson=JsonConvert.DeserializeObject(toJson,新的JsonSerializerSettings
{
TypeNameHandling=TypeNameHandling.Auto
});
公共抽象类JsonCreationConverter:JsonConverter
{
受保护的抽象T Create(类型objectType,JObject-JObject);
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(T)==objectType;
}
公共重写对象ReadJson(JsonReader reader,类型objectType,
对象存在值,JsonSerializer序列化程序)
{
尝试
{
var jObject=jObject.Load(读卡器);
var target=Create(objectType,jObject);
填充(jObject.CreateReader(),目标);
回报目标;
}
捕获(JsonReaderException)
{
返回null;
}
}
公共重写void WriteJson(JsonWriter writer,对象值,
JsonSerializer(序列化程序)
{
抛出新的NotImplementedException();
}
}
现在实现这个接口

public class SportActivityConverter : JsonCreationConverter<BaseSportActivity>
{
    protected override BaseSportActivity Create(Type objectType, JObject jObject)
    {
        BaseSportActivity result = null;
        try
        {
            switch ((ESportActivityType)jObject["activityType"].Value<int>())
            {
                case ESportActivityType.Football:
                    result = jObject.ToObject<FootballActivity>();
                    break;

                case ESportActivityType.Basketball:
                    result = jObject.ToObject<BasketballActivity>();
                    break;
            }
            
        }
        catch(Exception ex)
        {
            Debug.WriteLine(ex);
        }

        return result;
        
    }
}
公共类SportActivityConverter:JsonCreationConverter
{
受保护的重写BaseSportActivity创建(类型objectType,JObject JObject)
{
BaseSportActivity结果=空;
尝试
{
开关((ESportActivityType)作业对象[“activityType”].Value())
{
案例ESportActivityType.足球:
结果=jObject.ToObject();
打破
案例ESportActivityType.篮球:
结果=jObject.ToObject();
打破
}
}
捕获(例外情况除外)
{
Debug.WriteLine(ex);
}
返回结果;
}
}

你需要这个:我发现最好的结果来自于
typenameholling。所有这些
public abstract class JsonCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jObject);

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

    public override object ReadJson(JsonReader reader,Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        try
        {
            var jObject = JObject.Load(reader);
            var target = Create(objectType, jObject);
            serializer.Populate(jObject.CreateReader(), target);
            return target;
        }
        catch (JsonReaderException)
        {
            return null;
        }
    }

    public override void WriteJson(JsonWriter writer, object value,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
public class SportActivityConverter : JsonCreationConverter<BaseSportActivity>
{
    protected override BaseSportActivity Create(Type objectType, JObject jObject)
    {
        BaseSportActivity result = null;
        try
        {
            switch ((ESportActivityType)jObject["activityType"].Value<int>())
            {
                case ESportActivityType.Football:
                    result = jObject.ToObject<FootballActivity>();
                    break;

                case ESportActivityType.Basketball:
                    result = jObject.ToObject<BasketballActivity>();
                    break;
            }
            
        }
        catch(Exception ex)
        {
            Debug.WriteLine(ex);
        }

        return result;
        
    }
}