4
var custsType = Type.GetType("Customers");          
var customers = Json.Deserialize<custsType>(data);

This obviously fails. How do I reference the class by string name so I can supply it at runtime?

Also, I need to be able to have access to the actual strong typed object, not its string representation..

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
I Stand With Russia
  • 6,254
  • 8
  • 39
  • 67
  • I think this may be the duplicate you're looking for: https://stackoverflow.com/a/1606988/424129 – 15ee8f99-57ff-4f92-890c-b56153 Nov 03 '17 at 18:13
  • Since you don't know the type at compile time you can't use it as *customer.Name* So you should handle it dynamically. Then Just use(Json.Net) `var jobj = JObject.Parse(jsonstr);` and use its properties like `jobj["name"]`. using the keyword – L.B Nov 03 '17 at 18:21
  • *Referenced SO post doesn't return strong type. only dynamic object.* -- actually this is wrong. In the [referenced answer](https://stackoverflow.com/a/32371686/3744182) the JSON is deserialized into an object of the requested type -- but returned by a method whose return value signature is `object` which is the base type of all c# objects. See the [newtonsoft docs](https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConvert_DeserializeObject_2.htm) for details. – dbc Nov 03 '17 at 21:13

2 Answers2

6
var custsType = Type.GetType("Customers");          
var customers = JsonConvert.DeserializeObject(data, custsType);

The problem is that you're going to have difficulty using the object if its type is uncertain. Presumably the type name is a parameter, otherwise you would have just done

var customers = JsonConvert.DeserializeObject<Customers>(data);

It suggests that at compile time you don't know what type you expect this to return. The problem with that is that if you don't know the type at compile time, it's unclear what you can do with the object once you get it.

If you intend to access any properties of the object then you must have some assumption up front about what the type of the object would be. Otherwise you wouldn't expect the deserialized object to have that property.

The challenge isn't how to solve the problem, but how to reconsider the approach so that you don't have the problem in the first place.

Ideally you want to know the type that you expect at compile time, which would look like this again:

var customers = JsonConvert.DeserializeObject<Customers>(data, custsType);

Then if the data can't be deserialized to the expected type, it throws an exception because the caller must pass the correct type.

If you find yourself in a spot where a) you don't know what the type is, or b) you have to use reflection to find properties, then something has gone wrong, and it's good to back up until you can fix that.


Trying to access a property like this:

var name = myObject["Name"];

is easier than reflection, but it's ultimately the same thing as

var property = myObject.GetType().GetProperty("Name");
var name = property.GetValue(myObject);

In both cases you don't really know if there will be a "Name" property or not. Whatever parses the object into JSON is just using reflection behind the scenes.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • this is a great answer. not sure why its being voted down – I Stand With Russia Nov 03 '17 at 18:22
  • Yes it would work. but say how you would access to properties of `customers` . Reflection? – L.B Nov 03 '17 at 18:23
  • 1
    Maybe because it's an answer for what you're trying to do in a more specific sense, but it doesn't answer the question as asked. – Scott Hannen Nov 03 '17 at 18:23
  • I do need to access the properties, and I need the actual object, not the json representation – I Stand With Russia Nov 03 '17 at 18:24
  • @L.B You can't, which is the underlying problem. You can't know its type at compile time. – Scott Hannen Nov 03 '17 at 18:25
  • @ScottHannen Yes, Therefore I suggested 'JObject.Parse' which implements IDictionary – L.B Nov 03 '17 at 18:25
  • 1
    @L.B. That doesn't really solve the problem, though. If you don't know what the type is at compile time, how can you expect it to have a "name" property or any other property? – Scott Hannen Nov 03 '17 at 18:31
  • @ScottHannen In general you are right, but some properties' name might be stored somewhere like config, db etc. To make it short, OP is confused about accesing dynamic object's properties. And you fell into this trap too. – L.B Nov 03 '17 at 18:35
  • @L.B. I'd like to think that I'm pointing out the trap, not falling into it. If someone has gotten to the point where they need to use dynamic objects or reflection then it's often more helpful to highlight the underlying problem then to solve the one presented. – Scott Hannen Nov 03 '17 at 18:46
  • @ScottHannen As you might have guessed, I was referring to your original answer which doesn't answer :) – L.B Nov 03 '17 at 18:51
  • I reopened this question and marked the other one as dub of this since this thread contains more info – L.B Nov 03 '17 at 19:03
0

Using Json.Net you specify type name handler:

new JsonSerializerSettings
    {
         TypeNameHandling = TypeNameHandling.Objects,
         TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full
    }

see: https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm

Brad Patton
  • 4,007
  • 4
  • 34
  • 44