首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果JsonConvert.DeserializeObject<List<Object>>小于2个JSON对象,则ApiResponse获得异常

如果JsonConvert.DeserializeObject<List<Object>>小于2个JSON对象,则ApiResponse获得异常
EN

Stack Overflow用户
提问于 2020-11-14 23:52:44
回答 1查看 280关注 0票数 0

我正在尝试将JSON字符串转换为object。

我的模型课:

代码语言:javascript
复制
public class ResponseData<obj> where obj : class
{
    public string message { get; set; }
    public Boolean isSuccess { get; set; }
    public  obj data{ get; set; }
}

public class Registration
{
    public int id { get; set; }
    public int eventId { get; set; }
    public string eventTitle { get; set; }
    public string startDate { get; set; }
    public string status { get; set; }
}

JSON弦

代码语言:javascript
复制
{
  "message": "Success",
  "isSuccess": true,
  "data": [
    {
      "id": 6,
      "eventId": 1,
      "eventTitle": "Test Event",
      "startDate": "2020-10-10T00:00:00",
      "status": "Pending"
    },
    {
      "id": 1,
      "eventId": 4,
      "eventTitle": "dung test",
      "startDate": "2020-10-15T00:00:00",
      "status": "Denied"
    }
  ]
}

我的JsonConvert代码

代码语言:javascript
复制
ResponseData<IList<Registration>> responseListRegistration = JsonConvert.DeserializeObject<ResponseData<IList<Registration>>>(apiResponse);

Problem:只要JSON "data“有多个对象,我的代码就能正常运行。当“数据”只有一个对象时,它会遇到异常。问题是“数据”可能有一个以上的对象。

'System.Collections.Generic.IList`1APT_Admin.Models.Registration‘:无法将当前

对象(例如,{“名称”:“值”})反序列化为类型JsonSerializationException,因为该类型需要一个JSON数组(例如,1,2,3)才能正确地反序列化。要修复此错误,要么将JSON更改为JSON数组(例如,1,2,3),要么更改反序列化类型,使之成为可以从JSON对象反序列化的普通.NET类型(例如,不像整数这样的原始类型,而不是数组或列表之类的集合类型)。还可以将JsonObjectAttribute添加到类型中,以强制它从JSON对象反序列化。路径'data.id',第1行,位置51。

我试过:List,IList,IEnumerable,但都一样。

1对象JSON

代码语言:javascript
复制
{
  "message": "Success",
  "isSuccess": true,
  "data": {
    "id": 6,
    "eventId": 1,
    "eventTitle": "Test Event",
    "startDate": "2020-10-10T00:00:00",
    "status": "Pending"
  }
}

谢谢你的阅读

EN

回答 1

Stack Overflow用户

发布于 2020-11-15 01:02:00

要在一个类模型中反序列化两个不同的json结构,您需要使用自定义JsonConverterJsonReader允许您读取第一个令牌。如果是[,则需要反序列化为list。如果它是一个{,一个对象。

代码语言:javascript
复制
void Main()
{
    var json = "{ \"message\": \"Success\", \"isSuccess\": true, \"data\": [ { \"id\": 6, \"eventId\": 1, \"eventTitle\": \"Test Event\", \"startDate\": \"2020-10-10T00:00:00\", \"status\": \"Pending\" }, { \"id\": 1, \"eventId\": 4, \"eventTitle\": \"dung test\", \"startDate\": \"2020-10-15T00:00:00\", \"status\": \"Denied\" } ]}";
    var json2 = "{ \"message\": \"Success\", \"isSuccess\": true, \"data\": { \"id\": 6, \"eventId\": 1, \"eventTitle\": \"Test Event\", \"startDate\": \"2020-10-10T00:00:00\", \"status\": \"Pending\" }}";

    var multiItems = JsonConvert.DeserializeObject<ResponseData<IList<Registration>>>(json);
    var singleItem = JsonConvert.DeserializeObject<ResponseData<IList<Registration>>>(json2);
}

public class ResponseData<T> where T : class
{
    public string message { get; set; }
    public Boolean isSuccess { get; set; }

    [JsonConverterAttribute(typeof(ItemOrListConverter))]
    public T data { get; set; }
}
public class Registration
{
    public int id { get; set; }
    public int eventId { get; set; }
    public string eventTitle { get; set; }
    public string startDate { get; set; }
    public string status { get; set; }
}

public class ItemOrListConverter : Newtonsoft.Json.JsonConverter
{
    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        var itemType = objectType.GetGenericArguments()[0];
        var listType = typeof(List<>).MakeGenericType(itemType);

        var result = Activator.CreateInstance(listType) as IList;

        if (reader.TokenType == JsonToken.StartObject)
        {
            var singleObject = serializer.Deserialize(reader, itemType);
            result.Add(singleObject);
        }
        else if (reader.TokenType == JsonToken.StartArray)
        {
            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.EndArray)
                    break;

                var singleObject = serializer.Deserialize(reader, itemType);
                result.Add(singleObject);
            }
        }

        return result;
    }

    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }
}

System.Text.Json

代码语言:javascript
复制
void Main()
{
    var json = "{ \"message\": \"Success\", \"isSuccess\": true, \"data\": [ { \"id\": 6, \"eventId\": 1, \"eventTitle\": \"Test Event\", \"startDate\": \"2020-10-10T00:00:00\", \"status\": \"Pending\" }, { \"id\": 1, \"eventId\": 4, \"eventTitle\": \"dung test\", \"startDate\": \"2020-10-15T00:00:00\", \"status\": \"Denied\" } ]}";
    var json2 = "{ \"message\": \"Success\", \"isSuccess\": true, \"data\": { \"id\": 6, \"eventId\": 1, \"eventTitle\": \"Test Event\", \"startDate\": \"2020-10-10T00:00:00\", \"status\": \"Pending\" }}";

    JsonSerializer.Deserialize<ResponseData<IList<Registration>>>(json).Dump();
    JsonSerializer.Deserialize<ResponseData<IList<Registration>>>(json2).Dump();
}

public class ResponseData<T> where T : class
{
    public string message { get; set; }
    public Boolean isSuccess { get; set; }

    [JsonConverterAttribute(typeof(ItemOrListConverterFactory))]
    public T data { get; set; }
}
public class Registration
{
    public int id { get; set; }
    public int eventId { get; set; }
    public string eventTitle { get; set; }
    public string startDate { get; set; }
    public string status { get; set; }
}

public class ItemOrListConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
        => typeToConvert
            .GetInterfaces()
            .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>));

    public override System.Text.Json.Serialization.JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        var itemType = typeToConvert
            .GetInterfaces()
            .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            .GetGenericArguments()[0];

        if (typeToConvert.IsInterface)
        {
            typeToConvert = typeof(List<>).MakeGenericType(itemType);
        }

        return (JsonConverter)Activator.CreateInstance(
            typeof(ItemOrListConverter<>).MakeGenericType(typeToConvert),
            args: new object[] { itemType });
    }
}

public class ItemOrListConverter<T> : JsonConverter<T>
{
    private readonly Type _itemType;

    public ItemOrListConverter(Type itemType)
    {
        _itemType = itemType;
    }

    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var result = (IList)Activator.CreateInstance(typeToConvert);

        if (reader.TokenType == JsonTokenType.StartObject)
        {
            var singleObject = JsonSerializer.Deserialize(ref reader, _itemType, options);
            result.Add(singleObject);
        }
        else if (reader.TokenType == JsonTokenType.StartArray)
        {
            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndArray)
                    break;
                var singleObject = JsonSerializer.Deserialize(ref reader, _itemType, options);
                result.Add(singleObject);
            }
        }

        return (T)result;
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64839867

复制
相关文章

相似问题

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