简体   繁体   中英

C# convert Json string property to T generic type

I have a class Type with string property Name and T property value. I am receiving a Json object with different properties, two of them are name and value.

I am creating with reflection the Type (in the example I created explicity a boolean) and I need to assign the received String value to the Type.Value property that can be any type.

How can I do that? The type can be int string, List (any known type) or a new type that I have created. I don't want to switch over the received string type name to create a specific value type. I want a generic way to do it to avoid updating this method every time that I create a new type in my system. If I create the Type class instance with reflection, I want also to update the value property on runtime without knowing the type.

My code doesn't handle the deserialization (this is taken place in other code that I don't have access to. Even with acess, the project where the deserialize is taken place, doesn't recognize the custom types because it is a common/util project. So in this case, I need to focus only on converting a string value to a T value.

public class Type<T>
{
  public string Name { get; set; }
  public Type Type => typeof(T)
  public T Value { get; set; }
}

public MyResultObject
{
    public string ReqId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}


  var jsonResult = myResultObject //type of MyResultObject
  var type = new type<bool>(); //in my code this is created with reflection
  type.Name = jsonResult.Name;
  type.Value = jsonResult.Value as bool ??? //I want to convert the string Value to the explicit type that can be any T type


Your sample doesn't demonstrate the issue well enough. If you know <T> of Type<T> just add a method on your Type<T> class that does the parsing via JsonConvert from NewtonsoftJson or JsonSerializer from System.Text.Json and problem will be solved. Am I missing something here?

public class Type<T>
{
    public string Name { get; set; }
    public Type GenericType => typeof(T);
    public T Value { get; set; }

    public void SetValueFromString(string value)
    {
        Value = JsonConvert.DeserializeObject<T>(value);
    }
}

The best approach depends on details you haven't included.

If you don't know the type at the point where you're deserializing, but you do know the type at some later point in your code, one solution could be to leave the Value property as a JToken, and then convert it when your code knows what type it needs:

public MyResultObject
{
    public string ReqId { get; set; }
    public string Name { get; set; }
    public JToken Value { get; set; }
}
type.Value = jsonResult.Value<bool>(); // or .Value<T>()

If you need to deserialize the object to the right concrete type but you don't know at compile-time what that type might be, JSON.NET has a built-in feature to handle this: TypeNameHandling . If you serialize and deserialize your objects using serializer options like this:

new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
}

... then you can make your Value property an object and JSON.NET will automatically add type metadata into the serialized object so that it can be serialized to the right type.

There are two potential down-sides to that approach, though. One is that you have to be in control of both serialization and deserialization. The other is that there may be security implications if someone you don't trust is providing the JSON: they could instantiate some random object type that you don't expect them to be able to create.

There's a middle-ground approach where you use a custom type converter to determine which type of object to create based on the value of something else on the JSON object, but you have more control over which types of objects might be created, and how that gets represented in the JSON.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM