Serialize an array into JSON objects using .NET - c#

The serialization of the array returns the following JSON:
[{"Code":"AAAA","Description":"Description of AAAA"},{"Code":"BBBB","Description":"Description of BBBB"}]
My goal is to return the following JSON:
{"AAAA":{"Description":"Description of AAAA"},"BBBB":{"Description":"Description of BBBB"}}

You can achieve something simliar (not exactly the same you are expecting) if instead of serializing an array, build a temporary Dictionary and serialize it.
var dict = new Dictionary<String, YourClass>();
foreach (YourClass yourObj in listOfObjs)
{
dict[yourObj.Code] = yourObj;
}
// then serialize "dict"
You could add a rule to your JSON serializer to make it avoid serializing "code" property in YourClass, and you will end up with a JSON object exactly as you show in your example.

You'll need to either use a class that has the "AAAA" and "BBBB" properties, or you'll need to serialize a dictionary instead. As it is, you're serializing an array and getting an array.

The table on this blog post shows several search starting points.
.Net has built-in System.Web.Script.Serialization.JavaScriptSerializer, here, with examples
The .Net one doesn't specially serialize Dictionary the way you want, but some of the others do, I believe. However, I think there are reasons NOT to want a general serialization routine the way you've requested - though I can't list them certainly.

Related

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.

Deserializing a child into an object

I've tried some examples on here but am tearing my hair out.
I do a query and it returns JSON, inside the JSON are lots of hashes, eg.
{ "gjwiegjeigj": { ....}, "gjeeigjwoeigj": {...} ... }
I want to loop through each of these, and deserialize the contents into an object.
I've created the object, myObject which has all the fields, but I am stuck on deserialising.
I can deserialise straight from the base object using JsonConvert.DeserializeObject but I can't do that, I need to loop through and do that to the children.
I want an array of my custom objects with all the fields taken from the Json as a result of this, I don't care about the title of each one (the garbage hash).
Any ideas? I know I can loop through, which gives me lots of JTokens but that's where I get stuck.
Edit: Reading your question again, you mention both knowing and not knowing all the fields. It sounds like you really don't know exactly what fields the JSON string will contain.
For cases like this, I suggest you use dynamic -- this is where it shines. If you do know all the field names, your class should be deserializing without any issue.
What have you tried? Show us some real code, and real exceptions or problems.
To deserialize into a list of dynamic objects is simple:
dynamic toReturn = JsonConvert.DeserializeObject<List<dynamic>>(rawJson);
You should get back a list of dynamic objects. You can poke it for the fields you want:
Console.WriteLine(toReturn.First().gjwiegjeigj);
So I figured it out, basically to get from a collection JTokens which is what I get when I iterate through .Children() on my JSON object, I can either cast it to a JProperty and do .Name to get the name or .Value to get the value, or I can deserialize directly into an object, essentially like this:
MyObject record = (MyObject)JsonConvert.DeserializeObject(myRow.Children().First().ToString(), typeof(MyObject), settings);
Then I don't know need to know the name of the property I am deserializing.

Parse/Encode JSON without Deserializing/Serializing classes

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);

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);

JSON Serialization of Dictionary into name:value instead of {name:name, value:value}

Using ASP.NET 4.0 C#, how would I be able to change the serialization of a list containing name/value object into a JSON object that is of the format:
{
name:value,
name1:value1,
name2:value2
}
Instead of
{
{name:name, value:value},
{name:name1, value:value1},
{name:name2, value:value2}
}
The name/value object in the dictionary is dynamic in terms of the keys that will exist inside. One workarounds would be to create custom object which will have the explicit properties available - However this approach is not scalable, therefore this question :)
Thanks.
You could implement a custom JavaScriptConverter, then you're in full control of the serialization. Or put all your properties into an IDictionary and JSON that and I think it will come out in the format you're after.

Categories