A project I am working on is consuming Web API's returning heterogeneous JSON, I don't understand why a webservice API would need to return different object graphs, but that is what is being returned.
My questions are
Is it usual/common practice to return different object graphs by the same api? By different object graph I mean a varying complex object that might have or not have some other complex objects as properties. It would have seem reasonable if the same properties returned for every call, either having a null value or a complex object as their values, but the properties being completely omitted in the response makes it hard to have a C# class to desrialise against.
How is JSON heterogeneous (de)serialisation handled in C#? Is reflection and run time code generation preferred method for this? or using dynamic/expando object?
It makes sense for some APIs to return different objects when some fields that happen to be complex objects are omitted because they do not contain information sometimes, or an endpoint returns different objects based on different parameters. Not sure if there are other cases.
As for different JSON, you have to know a little bit about what data is returned by the API and getting at least the data you need. You can use Json.NET and deserialize to a class or to a dynamic object if you are not entirely sure what to expect or don't want to create a class for it.
I also advise to read the API documentation, or do some sort of (boundary?) testing with the parameters to figure out what data to expect.
Related
I'm currently evaluating this library from a security perspective. Since YAML can be used to serialize objects, I was wondering if the defaults provided by the parser are set such that deserialization of arbitrary objects is prevented.
Putting it differently:
What are the steps needed to allow for the creation of any type of object give a YAML string containing the definition of a specific type?
From what I could tell going through the documentation, this behaviour is not easily reproducible, since the deserializer expects a type of an object to populate with the given data.
As a second, related question: Are validation checks that are present during the creation of objects (e.g. "Age" property can not be larger than 130 and smaller than 0) or when using a getter/setter pattern being used when creating the object, or is it possible to create objects that have unexpected data inside them that way?
In the Newtonsoft docs for CustomCreationConverter, it says:
"A more complicated scenario could involve an object factory or service locator that resolves the object at runtime."
I'm dealing with such a scenario where I have to hydrate a persistent object with an incoming DTO (which is in JSON). To hydrate the persistent object, I have to first load it using a service call. I can make this call during deserialization using CustomCreationConverter. Or I can consume the JSON as an ExpandoObject and transitively assign all members. Complexity is not much as the object graph is small.
Something about making service calls during deserialization does not seem right. It makes testing more complicated as I would have to first load that object into memory to be able to deserialize it. This also screams tight coupling.
So my question is: Is it a good idea to make service calls during deserialization in this scenario?
As I understand it, you are doing this steps:
Call the deserialization
In a CustomCreationConverter you retrieve a pre-populated object instance via a remote Service
Json.Net does it's thing on the retrieved instance.
Well, it seems to me you could make use of the PopulateObject method, like so:
var obj = RemoteService.Retrieve(id);
Newtonsoft.Json.JsonConvert.PopulateObject(jsonString, obj);
This way you keep your code simple (albeit less fun) and testable.
I want to deserialize an object graph in C#, the objects in the graph will have object and collection properties, some of the properties may be private, but I do not need to worry about cyclic object references. My intent is to use the deserialized object graph as test data as an application is being built, for this reason the objects need to be able to be deserialized from the XML prior to any serialization. I would like it to be as easy as possible to freely edit the XML to vary the objects that are constructed. I want the deserialization process not to require nested loops or nested Linq to SQL statements for each tier in the object graph.
I found the DataContractSerializer lacking. It can indeed deserialize to private fields and properties with a private setter but it appears to be incredibly brittle with regard to the processing of the XML input. All it takes is for an element in the XML to be not in quite the right order and it fails. What's more the order it expects the data to be declared in does not necessarily match the order the object members are declared in the class declaration, making it impossible to determine what XML will work without having the data in the objects to start with so that you can serialize it and check what it expects.
The XmlSerializer does not appear to be able to serialize to non-public data of any type.
Since the purpose is to generate test input data for what might be quite simple applications during development I'd rather not have to resort to heavyweight ORM technologies like Entity or Nhibernate.
Is there a simple solution?
[Update]
#Chuck Savage
Thanks very much for your reply. I'm responding in this edit due to the comment character limit.
In the technique you suggested the logic to deserialize each tier of the object hierarchy is maintained in each class, so in a sense you do have nested Linq to SQL just spread out across the various classes involved. This technique also maintains a reference to the XElement from which each object gets its values in each class, so in that sense it isn't so much deserialized as just creating a wrapper around the XML. In the scenario I have in mind I'd ideally like to be deserializing the actual business objects the application will use so an XML wrapper type object like this wouldn't work very well since it would require a distinctly different implementation for test usage compared to production usage.
What I'm really after is something that can do something akin to what the XmlSerializer can do, but which can also deserialize private fields, (or at least properties with no setter). The reason being that the XmlSerializer does what it does with minimal impact on the 'normal' production use of the classes involved (and hence no impact on their implementation).
How about something like this: https://stackoverflow.com/a/10158569/353147
You will have to create your own boilerplate code to go back and forth to xml, but with the included extensions that can be minimized.
Here is another example: https://stackoverflow.com/a/9035905/353147
You can also search my answers on the topic with: user:353147 XElement in the StackOverflow search.
I ran in to a fellow programmer and was discussing a method i needed to write, and in an OOP aspect, the a Dictionary<T,U> is perfect. But, i voiced concerns about the XML size and structure that it is translated to during serialization. So my buddy, in a very direct manner, said i should be using a wrapper object that contains the key and value, and return a list of them instead of a dictionary. Are there some .NET objects that just shouldnt be serialized over SOAP, and simpler, custom objects should be created instead?
The main things you need to worry about are:
Don't send unnecessary information.
Dont make too many service calls.
Try to balance size of data against number of calls (optimally reduce both of these to a minimum).
As a rule most people avoid passing data structures which contain complicated logic, such as Dictionary.
Serializing a List is fine (it will be serialized as an IEnumerable).
Don't feel that your data objects have to look like your Entity objects - think of packets of information rather than Entities. When you receive the data at the client end you should convert it into Entity objects.
I have several webservices working as an API for my database, built in C#, WCF 4, returning json and xml format. Currently they work with specific Typed objects, but i want to be able to return dynamic data. Somewhat like what the Youtube API does, you can send in the "fields" variable, and only get the specified datafields back.
I'm thinking i could probably use the Dynamic type for this somehow, but I havn't used it much and have no idea where to begin. Ideally if someone could point me to a project where this has been implemented i could learn from there, or if someone has an idea on how to implement this.
You can return IDictionary. The JSON serializer will pick it up and serialize correctly.