Parse/Encode JSON without Deserializing/Serializing classes - c#

I'm looking for a JSON parser and encoder for .NET that can parse JSON into its own data structure which I can then navigate, as opposed to directly deserializing it into a class. In Java, I use Jettison's JSONObject and JSONArray which is dead easy to use.
There are a number of reasons why I don't want to (de)serialize:
Serializers tend to add metadata to the JSON and require that metadata for deserialization (e.g. fastJSON and JSON.NET add type info).
I don't want the hassle of having to create a bunch of classes to handle all the different types of data. Also, I want to be able to ignore fields I'm not interested in rather than have to add properties to them.
Is there anything available or do I have to port a subset of Jettison?

The disadvantages of serialization that you point out aren't really there, at least in the case of JSON.NET:
JSON.NET doesn't add any metadata by default. You can tell it to add the metadata if you need it (for example, when one property can hold values of different types), but it's optional.
You replace the hassle of creating classes with the hassle of working with strings and casts and I think that's much worse. Also, you can ignore fields you're not interested in, just don't add them to your types.
But, if you really want to do that, you can. The equivalent types are JObject and JArray, so, if you want to deserialize some object, use:
JObject obj = JsonConvert.DeserializeObject<JObject>(json);
As another option, you don't have to specify the type you want at all, ant it will return either JObject or JArray:
object objectOrArray = JsonConvert.DeserializeObject(json);

Related

How to ensure that the class library represents the Json Schema perfectly

I have a JSON Schema, and a class library.
I am able to serialize this class, then convert back successfully to object.
To test it, I create a random object, serialize it.
Then convert to object and check its validity.
And deserialize it just to be sure about the values.
The code below works perfectly - but
I want to be absolutely sure that the class library represents the Json Schema.
Is there a way to achieve this? I found some online tools tries to create the class library from given schema, but none of them were so useful.
// Create random object.
MyObject myObject = new MyObject().CreateRandomMyObject();
// Serialize it.
string JSONObjectText = JsonConvert.SerializeObject(myObject);
// Check if schema is valid.
JSchema schema = JSchema.Parse(txtSchema.Value);
// Check if the serialized object is valid for schema.
JObject jsonObject = JObject.Parse(JSONObjectText);
IList<string> errorMessages;
bool valid = jsonObject.IsValid(schema, out errorMessages);
// Check if the serialized object can be deserialized.
MyObject myObjectReDeserialized = (MyObject)JsonConvert.DeserializeObject(JSONObjectText, typeof(MyObject), new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Error });
A way to do test-oriented assertion of your mapping is to use FsCheck to generate plenty of random objects and then assert what you want to hold from them: in this case, that
their serialization is valid given the schema,
they can be deserialized back to the same object. (You should make sure you are using structural equality there.)
To be precise, such approach only checks that everything described by your objects is representable by the schema. You might want to do the other way also -- that every JSON that conforms to the schema is representable by your objects. Again, you can generate many possible JSONs conforming to the schema and check that
they can be deserialized to your objects,
reserialization of those objects gives you the same JSON you started with.
Beware though, this might not be practical: FsCheck probably don't have some nice, first-class support for JSON schema based generation out-of-the-box.
If the schema you have is going to change in the future, it would be really great to have a way to generate corresponding objects to have strong types even at the boundary of your application. Have you tried Swagger Codegen? Swagger describes it's endpoints using subset of JSON Schema. The corresponding tooling might help you.

Dummy Objects Good or Bad

I am working on a project that communicates a lot of data with a server. This data is in a json format. We end up creating a lot of dummy objects to parse the json data. This leads to having a lot of classes that just contain class members. Is there a better way of doing things?
thanks
Assuming that you are using NewtonSoft's JSON parser or something similar, you have a couple of choices here. The usual use case here is to deserialize to a named type, thus:
var parsedMessage = JsonConvert.DeserializeObject<Message>(content.AsString());
If you have many types for each differnet JSON message type you wish to receive and wish to avoid to, you can do the following:
var parsedMessage = JsonConvert.DeserializeObject<dynamic>(content.AsString());
This will give you a dynamic object that you can inspect and should also work given other Json libraries. Alternatively, NetwtonSoft also provides the following method:
public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject);
This will allow you to deserialize to an anonymously typed object rather than a dynamic object.

How to deserialize JSON into a List<KeyValuePair<string,string>> set

I have some JSON data :-
{
"mail":"mitch#domain.com",
"givenName":"User",
"sn":"Name",
"uid":"mitch",
"gecos":"User Name"
}
What I'm trying to do is de-serialize this into a List<KeyValuePair<string,string>>
I would normally do a dictionary, however some key's may be duplicated - this is the representation that is automatically generated by .NET when I pass a List<KeyValuePair<string,string>> object into the System.Web.Script.Serialization.JavaScriptSerializer class.
When I just plug the serialized object into the System.Web.Script.Serialization.JavaScriptDeserializer I get a empty response back.
From what I can see it should not be possible using the JavaScriptSerializer. The only way for customizing its behavior is by means of a JavaScriptConverter class, that will allow you to customize the serialization/deserialization process. Unfortunately both methods will pass an IDictionary for the properties, therefore the duplicated names are already merged. You might want to look into either a different format for your JSON or a different serialization library such as JSON.net which is way more customizable.

Generic serializer with ProtoBuf.net

I'm attempting to write a generic serializer using protobuf.net v2. However I'm running into some issues which make me wonder if perhaps what I'm doing is impossible. The objects to be serialized are of an indeterminate type to which I don't have access so I'm attempting to walk the object and add its properties to the type model.
var model = TypeModel.Create();
List<string> propertiesToSerialize = new List<string>();
foreach (var property in typeToSerialize.GetProperties())
{
propertiesToSerialize.Add(property.Name);
}
model.AutoAddMissingTypes = true;
model.Add(typeToSerialize, true).Add(propertiesToSerialize.ToArray());
For simple objects which contain only primitives this seems to work just fine. However when working with an object which contains, say, a Dictionary<string,object> I encounter an error telling me that no serializer is registered for Object.
I did look at serializing a Dictionary<string,object> in ProtoBuf-net fails but it seems the suggested solution requires some knowledge and access to the object being serialized.
Any suggestions on how I might proceed?
protobuf-net does not set out to be able to serialize every scenario (especially those dominated by object), in exactly the same way that XmlSerializer and DataContractSerializer have scenarios which they can't model. In particular, the total lack of metadata in the protobuf format (part of why it is very efficient) means that it is only intended to be consumed by code that knows the structure of the data in advance - which is not possible if too much is object.
That said, there is some support via DynamicType=true, but that would not currently be enabled for the dictionary scenario you mention.
In most cases, though, it isn't really the case that the data can be anything; more typically there are a finite number of expected data types. When that is the case, the object problem can be addressed in a cleaner way using a slightly different model (specifically, a non-generic base-type, a generic sub-type, and a few "include" options). As with most serialization, there are scenarios were it may be desirable to have a separate "DTO" model, that looks closer to the serialization output than to your domain model.
A final note: the GetProperties()/Add() approach is not robust, as GetProperties() does not guarantee any particular order to the members; with protobuf-net in the way you show, order is important, as this helps determine the keys to use. Even if the order was fixed (sorting alphabetically, for example), note that adding a member could be a breaking change.

How to dynamically create a JSON object in c# (from an ASP.NET resource file)?

I need to serialize the strings from a resource file (.resx) into a JSON object. The resource file's keys are in flux and thus I cannot just create a C# object that accepts the appropriate values. It needs to be a dynamic solution. I am able to loop through the key-value pairs for the file, but I need an easy way to serialize them to JSON.
I know I could do:
Object thing = new {stringOne = StringResource.stringOne; ...}
But, I'd rather have something like:
Object generic = {}
foreach (DictionaryEntry entry in StringResource) {
generic.(entry.Key) = entry.Value
}
Or should I just create a custom JSON serializer that constructs the object piecemeal (i.e. foreach loop that appends part of the JSON string with each cycle)?
EDIT
I ended up writing a quick JSON serializer that constructs the string one field at a time. I didn't want to include a whole JSON library as this is the only use of JSON objects (for now at least). Ultimately, what I wanted is probably impractical and doesn't exist as it's function is better served by other data structures. Thanks for all the answers though!
If you're using C# 4.0, you should look at the magical System.Dynamic.ExpandoObject. It's an object that allows you to dynamically add and remove properties at runtime, using the new DLR in .NET 4.0. Here is a good example use for the ExpandoObject.
Once you have your fully populated ExpandoObject, you can probably easily serialize that with any of the JSON libraries mentioned by the other excellent answers.
This sounds like an accident waiting to happen (i.e. creating output prior to cementing the structure), but it happens.
The custom JSON serializer is a compelling option, as it allows you to easily move from your dictionary into a JSON format. I would look at open source libraries (JSON.NET, etc) to see if you can reduce the development time.
I also think setting up in a slightly more structured format, like XML, is a decent choice. It is quite easy to serialize from XML to JSON using existing libraries, so you avoid heavy customization/
The bigger question is what purposes will the data ultimately serve. If you solve this problem using either of these methods, are you creating bigger problems in the future.
Probably I would use JSON.NET and the ability to create JSON from XML.
Then, you could create an XML in-memory and let JSON.NET convert it to JSON for you. Maybe if you dig deeper into the API, there are other options, too.
Newtonsoft is a library that has all kinds of nifty JSON tools...among them, on-the-fly one-line serializer and deserializers...check it out, it's my favorite JSON library out there
http://james.newtonking.com/pages/json-net.aspx
If I remember correctly, it has a class that will convert JSON to a .NET object without having to create the .NET object first. Think it is in the Json.Convert class
The way I do it is:
var serialiser = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = serialiser.Serialize(data);
context.Response.Write(json);

Categories