In GSON, you can deserialize into a JsonObject, which in turns allows you to access JsonElements and call methods such as getAsString(), getAsInt(), etc...
This is incredibly useful for my use case: I am serializing data with JSON and sending it over a network. Data is sent along with protocol identifiers which tells the client how to process the data. I do not want to create a class for every different sort of protocol, so deserializing as a JsonObject allows me a lot of flexibility.
I can't find an analogous way to do this in C#. I figure I need to roll my own JsonElement/Object/Array/Primitive hierarchy, but I don't really know where to begin. Is that even the best way to do it?
I want to:
Deserialize json in C# into a structure which lets me access data as specific types, without using a class "skeleton" for the data.
EDIT:
I am restricted to .NET 3.5
JSON.NET can do this--you don't need to deserialize into a class:
int value = JObject.Parse(myJsonString)["property"]["subProperty"].Value<int>();
See the documentation for LINQ to JSON for more information.
Related
I have been provided a c# class generated through protogen.
I have a json response which I want to convert into object(map to the class generated from protogen).
How can I achieve this ?
The Json that I have is like:
Test {Id:"0000001" InsertDateTime:"4/12/2018 01:01:01" ModifyDateTime:"4/12/2018 01:05:10" ParentId:"0000001"
Sample{Id:"0000002" InsertDateTime:"4/12/2018 01:01:01" ModifyDateTime:"4/12/2018 01:05:10"}
}
The main class name is 'Test' and it has int, string properties as well as properties of type 'class' as well.
I want to convert this Json to 'protogen' generated class object.
protobuf-net only implements the binary Protocol Buffers (ProtoBuf) specification.
It is unclear whether by "json" you mean "general purpose JSON, nothing to do with ProtoBuf", or whether you mean "the Protocol Buffers JSON format added around 3.0".
If you mean general purpose JSON: then usually just about any JSON serializer will work fine - Json.NET is a good default, but other JSON serializers exist. This is because protobuf-net tries to work with idiomatic .NET objects, which means that it tends to play very nicely with other tools that work with idiomatic .NET objects.
If you mean the ProtoBuf-specific JSON, then I would suggest using Google's official C# ProtoBuf library, which implements this. I simply haven't had need or time to add support for this into protobuf-net, and to date adding it has been a very low priority for me - I simply haven't seen anyone asking for it from me.
If you have generic JSON, but the JSON layout is different to your protobuf model, then frankly I would recommend having two DTO models:
one that is designed to work with your JSON data and your chosen JSON serializer (such as Json.NET)
one that is designed to work with your ProtoBuf data and your chosen ProtoBuf serializer (such as protobuf-net)
and simply map between the two representations with regular C# code (or any auto-mapper tool of your choosing).
You can sometimes fight a serializer library to get it work with an object model that doesn't match the shape of the data, but in my experience this is a bad use of time and leads to brittle, buggy code.
I am considering using NO SQL databases such as MongoDb, RavenDb or any other ones recommend I would consider.
Can someone give me some advice, tutorials and useful links regarding my following question.
This system I want to write must be dynamic e.g. the model may change allot and should not be hard coded in C#.
For example if I had a JSON document saved holding ID, NAME, FULL NAME and then added a property called PHONENUMBER I would not want to rebuild the C# code or redeploy.
Is it possible to build C# models from a dynamic JSON? and then be able to manipulate it?
If so what library are most recommend for this type of system? What libraries work best with .NET?
This question is a step in to starting my university project.
Thanks for help & advice.
Yes, you can do that quite easily with RavenDB.
You can do it in one of two ways.
Either you will use a fully dynamic model, utilizing the C# dynamic keyword. That will let you do pretty much whatever you want, including adding properties at runtime, querying on runtime properties, etc.
However, a more common setup is that you'll use a lot of common properties (a customer has to have a name, for example). So you'll have a model that looks something like this:
public class Customer
{
public string Id {get;set;}
public string Name {get;set;}
public dynamic Props {get;set;}
}
The fixed properties are coded in C#, which helps you get into an easier, more consistent model and work with all the usual compiled tooling.
The dynamic stuff is in the Props property (which is usually initialized to ExpandoObject).
Note that you cannot do linq queries using dynamic. This is a limitation of C#, not RavenDB. You can still query dynamically using RavenDB, but you'll have to use the string based query API.
I implemented a Json.NET serializer wrapper that may help you:
https://github.com/welegan/RedisSessionProvider/blob/master/RedisSessionProvider/Serialization/RedisJSONSerializer.cs
I use it in my library which stores the contents of ASP.NET's Session object inside of Redis, which is a NoSQL option you did not mention. Still, given the typeless nature of Json, I imagine it will be applicable to your needs regardless of what NoSQL db you choose. The basic steps are:
Serialize:
Decide on a delimiter (I probably could have chosen a better one)
Store the type info (you can cache it for performance gains)
Store the object data after a delimiter
Deserialize:
Find the type info up to the delimiter
Deserialize the Type object
Pass Type as well as the object data to the library of your choosing. At the very least, Json.NET and ServiceStack.Json both expose serializers that will do the trick.
Edit
Seems I misunderstood part of your question. You want to be able to support adding json properties without redeploying your C#, and my example would strip out the extra properties during the serialize step back to the noSql db. You can use either a Dictionary<string, string> or ExpandoObject like ayende or mxmissile suggest, but keep in mind you will then have very few guarantees about the type of the properties of the object you get out.
In other words, you can freely add property names but as soon as you change the type of a property from int to long your code will break unexpectedly. Depending on your use case, that may or may not matter, just something to keep in mind.
Yes, using a Dictionary. However, I am not sure how those database systems handle dictionaries. Gracefully or not.
No, c# is compiled, so once that is done, there is no changing it without changing the source and compiling again. I think you should add some Javascript for that as it is a JS strong point.
I'm trying to serialize an array of objects into JSON in C#. By array I mean something like Object[] (not Array<Object>), I'm using a JsonMediaTypeFormatter as part of MVC (the serialization is happening automatically as part of the framework but I can override it). The output contains {"count":2,"value":[{...},{...},...]}" where the ... is the json representation of the object. I've looked around and haven't found much information about suppressing this behavior. I want the output to just be the [{...},{...},...] rather than the object with count and values properties. Does anyone know how to achieve this without manually writing the code to do the serialization?
You could consider an alternative framework like the JSON.NET framework. I don't know how much you can customize if you are using an in-built .NET object since there are public properties that are not being ignored. Not using the JSONMediaTypeFormatter much, if it allows you to ignore properties, consider overriding List or ArrayList to hide certain attributes.
I would recommend not returning an array directly as there is a security flaw that could be compromised in a client browser (if that is the consumer). See this reference to find out more.
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.
What is a better approach to serialize custom class: using XMLSerializer or BinarryFormatter and [Serializable] attribute on class?
It's not possible to answer this, without knowing how you will use the resulting file, and the lifetime of it.
The decision is based on the fact that it is harder to "upgrade" the binary format. If your object model changes, it won't deserialise correctly. But if you've implemented a custom XML serialisation/deserialisation, then you can handle the "new" cases appropriately, and life will be good.
So decide more about how you will use it, who you are sharing information with, and what the possible changes to the model are.
FWIW, I sometimes use both types of serialisation in a given project.
That really depends on how you use the serialized class. If you want to pass it to other programs or want to easily debug it, use XML (but mind that XMLSerializer might produce non-compliant XML output, like multiple root elements).
In all other cases, you can use the binary formatter. But note that XML is more suitable if you change the class later - you can use XMLIgnore and the like to keep the XML format intact.
The decision will sometimes also be made for you based on what the serialized output will be used for - while you could expose a WebService to take a binary array that is a binary serialized item, you couldn't utilize the web service easily from anything but .Net (and the end client would probably need a reference to the type).
Using XML means that the service could be exposed to any end client regardless of the platform/environment on the end client