【问题标题】:Deserialize List<T> with type from runtime使用运行时的类型反序列化 List<T>
【发布时间】:2020-12-01 15:55:21
【问题描述】:

我正在尝试反序列化来自 API 的响应,并在运行时检索类型:

var modelType = Type.GetType($"Namespace.{itemname}").GetType();

然后我调用一个泛型方法,将类型传入(带反射)。在 API 调用之后,我尝试从响应中反序列化它:

var obj= await response.Content.ReadAs<List<T>>();

但它给出了这个错误:

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“System.RuntimeType”,因为该类型需要 JSON 字符串值才能正确反序列化。

我也尝试将其读取为字符串,然后使用 JsonConvert

var str = await response.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject<List<T>>(str);

同样的错误。有人知道怎么做吗?谢谢!

【问题讨论】:

  • 您的问题中的T 是什么?它来自哪里?
  • T 总是一个简单的类(我想用 T 因为我有很多)
  • 你的T是modelType变量吗?
  • 认为 Type.GetType($"Namespace.{itemname}").GetType(); 是错误的:您解析类型,然后在“RuntimeType”类型的实例上调用“GetType”,因此您会得到类似类型的类型。您可能应该仔细检查该部分或发布更完整的示例?
  • @A.Chiesa 你是对的!现在正在工作!非常感谢!

标签: c# json .net


【解决方案1】:

问题出在var modelType = Type.GetType($"Namespace.{itemname}").GetType();这一行。

此代码通过名称 (Type.GetType($"Namespace.{itemname}")) 解析类型,然后在此类型实例上调用方法 GetType。这会为您提供实例的类型,令人困惑的是,System.TypeSystem.RuntimeType,具体取决于框架版本。

删除多余的GetType() 应该可以解决问题。

【讨论】:

    【解决方案2】:

    您不能将泛型与运行时类型一起使用。也就是说,有采用类型参数的序列化/反序列化重载。

    在您的情况下,由于您有一个 T 是运行时类型的 List,因此您需要反射以在运行时动态创建泛型类型,然后将其传递给第二个参数:

    var listType = typeof(List<>);
    var modelType = Type.GetType($"Namespace.{itemname}");
    var str = await response.Content.ReadAsStringAsync();
    var obj = JsonConvert.DeserializeObject(str, listType.MakeGenericType(modelType));
    

    【讨论】:

      猜你喜欢
      • 2012-09-09
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 2012-04-06
      • 1970-01-01
      相关资源
      最近更新 更多