2

I have a process that needs to be able to call on a function in the following manner.

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));
}

The code above does not compile. Next, I used John Skeet's answer to a 2011 question similar to mine.

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);
}

There is an overload non-generic and a generic overload with the same name and the method table lookup fails. I was able to get around that problem by calling into my function (non-ambiguous) similar to below.

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);
}

However, I am now back to where my custom conversion extension methods are being ignored because the de-serializer is ignoring my Type type.

Is this even possible. Of courseI could use the de-serialization version similar to:

object result = JsonConvert.DeserializeObject(payload);

However, my exercise is to use the JsonConvert.DeserializeObject<T>(payload) overload so that my converters can be invoked.

Any tips?

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Ross Bush
  • 14,648
  • 2
  • 32
  • 55
  • 1
    Have you tried this overload instead ? http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConvert_DeserializeObject_2.htm – aybe Apr 21 '17 at 21:57
  • @Aybe - I have not tried it, however, it looks interesting. I will try it out when i get home. Thanks. – Ross Bush Apr 21 '17 at 22:06

1 Answers1

2

You do not need to jump through hoops. JsonConvert.DeserializeObject has a non-generic overload that accepts a Type.

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));
}
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300