JSON convert dictionary to a list of key value pairs - json

I have a Dictionary <string, string>
If I Json.Encode this I get {"Apple":"Apples","Orange":"Oranges"}
How I can get this to:-
[{ value: "Apples", key: "Apple" }, { value: "Oranges", key: "Orange"}]
Preferably using Newtonsoft.Json or jQuery

Convert it to a list of key value pairs before passing to the JSON serializer:
JsonConvert.SerializeObject(new List<KeyValuePair<string,string>>(dictionary));

To reiterate my comment, changing the data type from an IEnumerable> (or IDictionary) to a IList> will also cause the serialization to work "correctly" a.k.a. serialize the data as a JavaScript array. In my current situation, my JavaScript is isolated in a separate .js file where Razor can't follow so using JsonConvert.SerializeObject wasn't an option.
Definitely an odd bit of functionality here. It would be great if anyone has some insight as to why JSON serialization reacts the way by default; bug or intentional?

Related

Flutter Nested JSON with a List String as a Value in the Key Pair

I'm hoping someone can help me. I've been stuck on this for a while now. I am reading a JSON from an API but I have not been successful in converting it and sending it back to my typeahead/autocomplete class. I have attempted several different ways of doing this including JSON Serializable until it wouldn't work and I figured out it won't do nested JSON. The JSON I am reading is not like any of the examples that I have found. I have watched multiple tutorials and read all over stackoverflow. The key value pair I need to read has a key as normal but the value is a list of strings. All of the examples I have found have an object with a key:value pair in the list[]. Can someone please tell me how to read and decode this the easiest way?
Here is an example of the exact JSON:
callback(
{
"status": {
"code": 0
},
"total": 6,
"dictionary_terms": {
"compound": [
"aspirin",
"Aspirine",
"Aspirin sodium",
"Aspirin anhydride",
"Aspirin methyl ester",
"Aspirin calcium"
]
}
}
)
Once you have the object that json.decode(callback) gives, you have a Map<String, dynamic>. So to access compounds in there:
_dynamicMap = json.decode(callback);
List<String> dictionary_terms_compound = _dynamicMap['dictionary_terms']['compound'];
Depending on where you are in null safety, you probably need to either check to make sure each key isn't null. ie, this would fail if dictionary_terms or compound don't exist...so you would need to check for it before you can get the value from it.
So assuming they exist, you might need to put:
List<String> dictionary_terms_compound = _dynamicMap['dictionary_terms']!['compound']!;
The dart definition of your dictionary_terms object is a
Map<String, Map<String,List<String>>>

Parsing Vector to Array String

I'm new to Rust.
I try to write a websocket client.
This is my format message:
"[integer, "string", object]"
Is there away to store all value in Vector something like:
let msg: Vec<interface> = vec![123, "event", AnyObject{}];
How to convert it into string and vice versa.
Thanks in advance
Conceptually speaking you want to use an enum. The type of enums used in rust are called tagged unions. Essentially you can think of them as enums which can hold data.
enum Interface {
Int(i32),
String(&'static str),
Object(AnyObject),
// etc
}
// You can then create a vec of different enum variants
let msg: Vec<Interface> = vec![Interface::Int(123), Interface::String("event"), Interface::Object(AnyObject{})];
Assuming you are referring to JSON, then the recommended solution is to use serde with serde_json. serde_json provides a Value enum you can use to represent JSON data in an unknown layout.
// Copied from serde_json docs
enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
However, you don't need to use Value directly (unless you want to) since serde_json provides a macro to make this easier by letting you format your code like JSON.
use serde_json::{json, Value};
let msg: Value = json!([123, "event", {}]);
// You can then serialize a Value into JSON format
println!("{:?}", msg.to_string());
// Output: "[123,\"event\",{}]"
I recommend reading through the overview since they have a bunch of convenient ways for working with JSON.

Nested object JSON serialization in WebAPI

I am using .NET 4.0, MVC 4, Web API. I have following data structure:
Dictionary<Actor, Int32> TopActorToMovieCount = new Dictionary<Actor, Int32>(10);
And following entry in WebApiConfig:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
In my Controller, I am returning TopActorToMovieCount this way:
[HttpGet]
public HttpResponseMessage HighestMovies()
{
return Request.CreateResponse(HttpStatusCode.OK, MvcApplication.TopActorToMovieCount);
}
But the JSON output it is giving is:
{"api.Models.Actor":137,"api.Models.Actor":125,"api.Models.Actor":99,"api.Models.Actor":96,"api.Models.Actor":83,"api.Models.Actor":82,"api.Models.Actor":81,"api.Models.Actor":79,"....
Why it is not giving JSON structure for object of Actor?
I am sure that I am missing something, bout couldn't figure out. I tried adding following, but it didn't work:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
PS: When I switch to XML output, it works fine.
See similar question here: Not ableTo Serialize Dictionary with Complex key using Json.net
In this case, you are using "Actor" as the Key of your dictionary. Dictionary stores key/value pairs. So when creating the JSON response, it interprets the "Actor" as a key which is converted to a string, and the "Int32" as the value thus giving you
{"api.Models.Actor":137} or {key:value}
because
Actor.ToString() would result in "api.Models.Actor"
Here's a link to the definition of Dictionary: https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx

Changing an immutable object F#

I think the title of this is wrong but can't create a title that reflects, in the abstract, what I want to achieve.
I am writing a function which calls a service and retrieves data as a JSON string. The function parses the string with a JSON type provider. Under certain conditions I want to amend properties on that JSON object and then return the string of the amended object. So if the response from the call was
{"property1" : "value1","property2" : "value2", "property3": "value3" }
I want to change property3 to a new value and then return the JSON string.
If the JsonProvider was mutable this would be an exercise like:
type JsonResponse =
JsonProvider<""" {"property1" : "value1",
"property2" : "value2",
"property3": "value3" } """>
let jsonResponse = JsonResponse.Parse(response)
jsonResponse.Property3 <- "new value"
jsonResponse.ToString()
However, this does not work as the property cannot be set. I am trying to ascertain the best way to resolve this. I am quite happy to initialise a new object based on the original response but with amended parameters but I am not sure if there is an easy way to achieve this.
For reference, the JSON object is much more involved than the flat example given and contains a deep hierarchy.
Yes, you would need to create a new object, changing the bits you want and using the existing object's values for the rest. We added write APIs for both the XML and JSON type providers a while back. You will notice the types representing your JSON have constructors on them. You can see an example of this in use at the bottom of this link

Why is GSON not parsing these fields properly? (FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)

I have a JSONArray of JSONObjects that I'm trying to parse with GSON. I'm using FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES. It's parsing correctly for most fields (so the FieldNamingPolicy is set correct), but I'm getting null returned for
{
"image_sq_48x48_url": "url1",
"image_sq_64x64_url": "url2",
"image_sq_96x96_url": "url3"
}
with field names
imageSq48x48Url
imageSq64x64Url
imageSq96x96Url
Maybe a better question would be what is the proper camelCase? I have also tried
imageSq48X48Url
imageSq48X48url
If I map with #SerializedName("image_sq_96x96_url") it parses/populates correctly.
Unfortunately those fieldnames in your JSON don't conform to what Gson looks for using that strategy.
If you create a POJO and serialize it, you can see what the issue is:
class MyPojo
{
String imageSq48x48Url = "hi";
}
The resulting JSON from Gson using that strategy is:
{"image_sq48x48_url":"hi"}
It doesn't consider/look at numeric digits as leading indicators / start of a "word".
If you rename the field to:
String imageSq_48x48Url;
It would work with your JSON example and that strategy.
Basically, you either need to create your own class that implements FieldNamingStrategy that will handle those JSON fieldnames the way you want, or do what you're doing with the #SerializedName annotation.