使用Json.Net反序列化时,在运行时将System.Type用作<t>

时间:2017-04-21 21:52:02

标签: c# .net generics json.net

我有一个过程需要能够以下列方式调用函数。

public static Task<string> Convert(string payload, Type type)
{
    JsonSerializerSettings settings = new JsonSerializerSettings().Configure();//<--- Pull in extension methods to handle custom types
    return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<type>(payload), settings));
}

上面的代码无法编译。接下来,我使用John Skeet's answer来解决与我类似的2011年问题。

public static string Convert(string payload, Type type)
{
    JsonSerializerSettings settings = new JsonSerializerSettings().Configure();
    //This clashes with another overload of DeserializeObject in the method table
    MethodInfo method = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string) });
    method = method.MakeGenericMethod(type);
    object[] arguments = new object[1];
    arguments[0] = payload;
    string result = (string)method.Invoke(null, arguments);

    return JsonConvert.SerializeObject(result, settings);
}

存在重载非泛型和具有相同名称的泛型重载,并且方法表查找失败。通过调用类似于下面的函数(非模糊),我能够解决这个问题。

public static string Convert(string payload, Type type)
{
    JsonSerializerSettings settings = new JsonSerializerSettings().Configure();
    //This clashes with another overload of DeserializeObject in the method table
    MethodInfo method = typeof(TestConverter).GetMethod("TestThis", new[] { typeof(string) });
    method = method.MakeGenericMethod(type);
    object[] arguments = new object[1];
    arguments[0] = payload;
    string result = (string)method.Invoke(null, arguments);

    return JsonConvert.SerializeObject(result, settings);
}

public static T TestThis<T>(string s)
{
    return JsonConvert.DeserializeObject<T>(s);
}

但是,我现在回到我的自定义转换扩展方法被忽略的地方,因为反序列化器忽略了我的Type类型。

这是否可能。当然,我可以使用类似于:

的反序列化版本
object result = JsonConvert.DeserializeObject(payload);

但是,我的练习是使用JsonConvert.DeserializeObject<T>(payload)重载,以便可以调用我的转换器。

任何提示?

1 个答案:

答案 0 :(得分:2)

你不需要跳过篮球。 JsonConvert.DeserializeObject有一个接受Type的非通用overload

public static Task<string> Convert(string payload, Type type)
{
    JsonSerializerSettings settings = new JsonSerializerSettings().Configure();//<--- Pull in extension methods to handle custom types
    return JsonConvert.SerializeObject(JsonConvert.DeserializeObject(payload, type), settings));
}