Output a JSON property name with a dash using an anonymous object - c#

I am using a third party API which is like this below. It uses Json serializer to output
public Output(string name, object value);
I have to place the following json string in my output file from C#
Output("somename", new {my-name : "somevalue"})
The issue is C# does not allow identifiers with dash (-). How do I achieve this ?
Tried putting raw value like below but it adds back slash (\) to the file output which is not going very well.
Output("somename", #"{""my-name"":""somevalue""}")
Any thoughts ?

Since you are using an anonymous object, the simplest workaround would be to create a Dictionary<string, string> instead:
Output("somename", new Dictionary<string, string> { { "my-name", "somevalue" } });
Serialization of a dictionary as a JSON object in which the dictionary keys are mapped to JSON property names is supported by many .Net JSON serializers including json.net and javascriptserializer and even datacontractjsonserializer when UseSimpleDictionaryFormat = true as noted here.
And if you have values of different types and are using a serializer that supports arbitrary polymorphism during serialization (Json.NET and JavaScriptSerializer do) you could use a Dictionary<string, object>:
Output("somename",
new Dictionary<string, object>
{
{ "my-name", "somevalue" },
{ "my-id", 101 },
{ "my-value", value },
});

Related

C# Serializing an objects into JSON but retain the name

So I'm trying to serialize a Dictionary:
Dictionary<string, List<MyClass>>
My class contains a property called MyPropery
However the string comes out as "{"List1":[{"MyProperty":[]}]}"
How would I be able to make it convert to {"List1":["MyClass":{"MyProperty":[]}]}
To achieve what you want, you would need something like:
var obj = new Dictionary<string, List<Dictionary<string, MyClass>>>();
As kalimag pointed out, ["attr": "value"] isn't a valid JSON. The serialization of the object obj, illustrated above, could yield something like:
{"List1": [{"MyClass": {"MyProperty": []}}]}
Which is a valid JSON.

Dynamically serialise JSON with the ability to omit entries

I am using an API that frustratingly requires you to omit optional parameters rather than pass them as null.
Also, data is slightly nested in the format:
{ data: { prop1: 5, prop2: 6, prop3: 7 } }
Previously I was converting it using a replace:
"{ data: { prop1: {prop1}, prop2: {prop2}, prop3: {prop3} } }"
.Replace("{prop1}", prop1)....
But it turns out that if a value is not provided the API I am sending this to will only accept it if it's not included in the JSON.
Rather than mess around with complex string concatenation (as I am not using model binding), I thought about simply creating a dictionary and serialising it to JSON.
If I do this:
Dictionary<string, int> props = new Dictionary<string, int>
{
{ "prop1", 6 },
{ "prop3", 7 },
};
string json = JsonConvert.SerializeObject(props, Formatting.Indented);
I can serialise whichever props I need nicely. Unfortunately you can see the way I need to send the data is contained within the data property of the json. I would need to put a dictionary inside my dictionary, but the dictionary is defined as string, int so that isn't possible. If I changed the type, then I'd not be able to put my props in.
To solve this I can see 2 possible clean ways:
Dynamically compose a JSON object somehow sorta like XML
eg. new JsonObject().AddNode("data").AddProperty("Prop1", 3).AddProperty("Prop3", 5).... etc.
Serialise from a dictionary object in a way that will let me include the nested property. Or, find a way to assign the json from a non-nested dictionary into the data property of a new json object.
I've not found a way to do this cleanly yet - alternatively another suggestion on solving this issue would be appreciated.
Not sure what your problem is with the dictionary approach. This works fine:
var props = new Dictionary<string, Dictionary<string, int>>
{
{ "data", new Dictionary<string, int>
{
{"prop1", 6},
{"prop3", 7}
}
}
};
var json = JsonConvert.SerializeObject(props, Formatting.Indented);

Easily working on a json object

I'm deserializing (or parsing) a json string to a c# object (using Json.NET) and getting a JObject. I want to iterate all the properties with the key "bla", in the same way iterating all xml elements that named "bla" with XElement.Elements("bla").
If it's not possible, I would like to deserialize my json string into a c# object, and work dynamically and recursively on my deserialized json object (my json string can have lists / arrays that can have objects of 2 types.
In the end after editing my object (changing values and removing or adding properties) I need to serialize my object back to a json string.
Which is the best and easiest way to use json serializing and deserializing?
my Json looks like this:
{"Families":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":"fghfgh"}]}]}
in conclusion, the json value is a json object that it's value is a list/array, the list/array can contain 2 "types" of objects, and one of these types also has a property which it's value is a json object that it's value is a list/array, and it goes like this recursively. sometimes the value of one of the props of the type that doesn't have a property which it's value is a json object that it's value is a list/array, can be a list/array itself, that can contain only 1 type of the two mentioned.
If you don't need a strongly-typed object, you can deserialize to a dictionary:
Dictionary<string, object> myObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
And then just use it as a dictionary:
myObject["Property"] = value;
Or
foreach(var propertyKey in myObject.Keys)
{
// do something with each property
Console.WriteLine($"{propertyKey} = {myObject[propertyKey]}");
}
Here's a fiddle
You can serialize it back after you are done
My json looks more like this:
{"Familys":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}]}
For JSON like this:
var json = #"{
""Families"":{
""Family"":[
{
""propA"":""Top""
},
{
""propA"":""Top.Lower"",
""Families"":{
""Family"":[
{
""propB"":""propB value""
},
{
""propA"":""Top.Lower.EvenLower"",
""Families"":{
""Family"":[
{
""propA"":""Top.Lower.EvenLower.EvenLower""
}
]
}
}
]
}
}
]
}
}";
Do something like this:
//calling code makes use of "dynamic" to make things clean and readable.
dynamic parsedJson = JsonConvert.DeserializeObject(json);
var allPropAValues = GetPropAValues(parsedJson);
//**** NOTE: this has our extra property ****
var jsonWithExtraStuffProperty = JsonConvert.SerializeObject(parsedJson);
//recursive function that reads AND writes properties
public static List<string> GetPropAValues(dynamic obj)
{
var propAValues = new List<string>();
//**** NOTE: the use of an added property ****
obj.ExtraStuff = new Random().Next();
//if we have a propA value, get it.
if (obj.propA != null)
propAValues.Add(obj.propA.Value);
//iterate through families if there are any. your JSON had Families.Family.
if (obj.Families != null)
foreach (dynamic family in obj.Families.Family)
propAValues.AddRange(GetPropAValues(family));
return propAValues;
}

how to serialize a json string to a form post data

I need to POST a JSON string to a page.
The page is external and out of my control, and it expects the post data to be in the web-form post format (key1=value1&key2=value2)
How can I convert the JSON string to this format?
This can be done by first deserializing your JSON to a Dictionary<string, string>, then iterating through the key-value pairs in the dictionary and building up a querystring from that.
However, keep in mind that querystring format (application/x-www-form-urlencoded) is not a hierarchical format, while JSON is. So your JSON object can only be a simple object with key-value pairs (no arrays or nested objects). If your JSON is more complicated than that, you will have to do some more work to flatten it before you can convert it to a querystring.
Demo:
class Program
{
static void Main(string[] args)
{
string json = #"
{
""key1"" : ""value1"",
""key2"" : ""value2"",
""int"" : 5,
""bool"" : true,
""decimal"" : 3.14,
""punct"" : ""x+y=z""
}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> kvp in dict)
{
if (!string.IsNullOrEmpty(kvp.Key) && !string.IsNullOrEmpty(kvp.Value))
{
if (sb.Length > 0) sb.Append('&');
sb.Append(HttpUtility.UrlEncode(kvp.Key));
sb.Append('=');
sb.Append(HttpUtility.UrlEncode(kvp.Value));
}
}
var postDataString = sb.ToString();
Console.WriteLine(postDataString);
}
}
Output:
key1=value1&key2=value2&int=5&bool=True&decimal=3.14&punct=x%2by%3dz
As was mentioned in the comments, you can use the FormUrlEncodedContent class to do the same thing. Replace the StringBuilder and foreach loop in the code above with the following (but note this approach requires async/await):
var formUrlEncodedContent = new FormUrlEncodedContent(dict);
var postDataString = await formUrlEncodedContent.ReadAsStringAsync();
You don't post JSON like that. You set the Content-Type header to "application/json" and then you simply fill the content body with the JSON as-is.
There is no built in support in C# or JSON.NET to serialize JSON into form post data, but you can probably use LINQ to JSON to write a translater yourself relatively easy, assuming the JSON format is simple enough.
Is the Json being passed in always the same? Your best bet is to deserialize the Json to a C# class then create your post data from that.

Serialize array of objects as one object with a named property for each object in C# with JSON serializer

I have a List that, when serialized as JSON gives me an array of objects. However, I need the serialized version to be structured as follows:
{
"item3":{
"id":3,
"name":"monkey"
},
"item4":{
"id":4,
"name":"turtle"
}
}
Currently, the JSON serialization is structured like this:
[
{
"id":3,
"name":"monkey"
},
{
"id":4,
"name":"turtle"
}
]
My goal is to be able to reference the array by item ID instead of numeric index (ie. arr["item3"].name instead of arr[0].name).
You might did that just putting the data into a dictionary is enough for JaveScripySerializer:
var dict = list.ToDictionary(
item => "item" + item.id);
(and serialize dict)
If not:
I don't have a PC handy for an example, but you should be able to:
write a wrapper class that encapsulated the list/array
use the JavaScriptSerializer class
after creating the serializer, associate the wrapper-type with a custom serializer
in the custom serializer, iterate over the data, adding a key to the dictionary per-item, i.e. data.Add("item"+i,list[i]);
You associate custom maps via RegisterConverters: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.registerconverters.aspx
Note you don't need to write a deserialize unless you need that too.
If you get stuck, I'll try to ad an example later.

Categories