Multiple models to json - json

Is there a way to create a json array string from multiple models for Windows 8.1 Store App. For example:
public class Foo
{
public string property1 {get;set;}
public string property2 {get;set;}
}
public class Foo2
{
public string value1 {get;set;}
public string value2 {get;set;}
}
I have multiple models. I'm using json.net to convert models to json string. I can also convert arrays of models.
My question is how can I create an array json string using these models like:
[
{
"property1":"string",
"property2":"string"
},
{
"value1":"string",
"value2":"string"
},
{
"property1":"string",
"property2":"string"
}
]
I'm really stuck and need your help.

One way to do this is to create abstract class BaseFoo that both Foo and Foo2 classes will inherit from:
public abstract class BaseFoo
{
}
public class Foo : BaseFoo
{
public string property1 { get; set; }
public string property2 { get; set; }
}
public class Foo2 : BaseFoo
{
public string value1 { get; set; }
public string value2 { get; set; }
}
Lets say that you initialize the list like this:
var list = new List<BaseFoo>
{
new Foo
{
property1 = "prop11",
property2 = "prop12"
},
new Foo2
{
value1 = "val1",
value2 = "val2"
},
new Foo
{
property1 = "prop21",
property2 = "prop22"
}
};
The serialization should look like this:
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects
};
var json = JsonConvert.SerializeObject(list, Formatting.Indented, settings);
And the produced json will look like this:
[
{
"$type": "ConsoleApplication23.Foo, ConsoleApplication23",
"property1": "prop11",
"property2": "prop12"
},
{
"$type": "ConsoleApplication23.Foo2, ConsoleApplication23",
"value1": "val1",
"value2": "val2"
},
{
"$type": "ConsoleApplication23.Foo, ConsoleApplication23",
"property1": "prop21",
"property2": "prop22"
}
]
The TypeNameHandling.Objects option is added for successful deserialization:
var deserializedList = JsonConvert.DeserializeObject<List<BaseFoo>>(json, settings);
You can exclude it and get the exact json string you need, if you do not need to deserialize it back. Although leaving it included shouldn't break any functionality but will increase the size of the json string.

Related

Access a dictionary with json-glib-1.0 in Vala?

I'm trying to access a json dict with json-glib but I can't figure out how to access it following Valadoc
I'm trying to access files, the dict looks like this:
"items": [
{
"kind": "webfonts#webfont",
"family": "ABeeZee",
"category": "sans-serif",
"variants": [
"regular",
"italic"
],
"subsets": [
"latin"
],
"version": "v12",
"lastModified": "2019-04-29",
"files": {
"regular": "http://fonts.gstatic.com/s/abeezee/v12/esDR31xSG-6AGleN6tKukbcHCpE.ttf",
"italic": "http://fonts.gstatic.com/s/abeezee/v12/esDT31xSG-6AGleN2tCklZUCGpG-GQ.ttf"
}
},
Someone can help?
You can use the deserialization features of GObject:
public class Obj : Object {
public string kind { get; set; }
public string family { get; set; }
public string category { get; set; }
public string[] variants { get; set; }
public int num { get; set; }
public string to_string () {
StringBuilder builder = new StringBuilder ();
builder.append_printf ("kind = %s\n", kind);
builder.append_printf ("family = %s\n", family);
builder.append_printf ("category = %s\n", category);
builder.append_printf(#"variants:[\n");
foreach (var item in variants)
builder.append_printf(#"\t$item\n");
builder.append_printf(#"]\n");
return (owned) builder.str;
}
}
void main (string[] args) {
string data = """
{
"kind" : "my string",
"family" : "ABeeZee",
"category" : "sans-serif",
"variants": [
"regular",
"italic"
]
}""";
var obj = Json.gobject_from_data (typeof (Obj), data) as Obj;
print (#"$obj");
}
This will output:
> vala console.vala --pkg json-glib-1.0
kind = my string
family = ABeeZee
category = sans-serif
variants:[
regular
italic
]

Deserializing json with dynamic property name

Similar question was asked here Serialize/Deserialize dynamic property name using JSON.NET. I am not able to make it work in my situation as below:
I have the following JSON
{
"notes": {
"data": [{
"book": {
"items": [{
"page": "page 1",
"comment": "Some notes"
},
{
"page": "page 1",
"comment": "Some notes"
}
]
}
},
{
"journal": {
"items": [{
"page": "page 1",
"comment": "Some notes"
},
{
"page": "page 1",
"comment": "Some notes"
}
]
}
},
{
"magazine": {
"items": [{
"page": "page 1",
"comment": "Some notes"
},
{
"page": "page 1",
"comment": "Some notes"
}
]
}
}
]
}
}
Created the following classes for JSON serialization:
public class TestParse
{
public Note Notes { get; set; }
}
public class Note
{
public IList<Data> Data { get; set; }
}
public class Data
{
public Source Source { get; set; }
}
[JsonConverter(typeof(MyConverter))]
public class Source
{
public IList<Items> Items { get; set; }
}
public class Items
{
public string Page { get; set; }
public string Comment { get; set; }
}
public class MyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Source);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
var jo = JObject.Load(reader);
var req = new Data
{
Source = jo.ToObject<Source>()
};
return req;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var req = (Source)value;
var jo = new JObject(
new JObject(req.Items));
jo.WriteTo(writer);
}
}
}
I am still not able to deserialize "Source." Any pointer is appreciated.
In the other question you referenced, the dynamic key was determined by the value of another property in the same object. Hence, a converter was needed.
In your situation, you have dynamic keys, but they are not dependent on anything.
You don't really need a converter here; you can just use a Dictionary to handle the dynamic keys.
Change this line in your Note class:
public IList<Data> Data { get; set; }
to this:
public IList<IDictionary<string, Source>> Data { get; set; }
and remove the [JsonConverter] attribute from your Source class. Then it should work.
(You can also delete the Data class as it is not needed.)
Fiddle: https://dotnetfiddle.net/80lIRI

Creating json object in mvc and returning from controller

I need to create the following in a loop, my has "name" and "id" where name will be used for the value property of the json object and id will be used for the "data" and query will be some string I can set.
I tried using keypair but could not figure out how to do this property. Any help would be appreciated.
{
"query": "Unit",
"suggestions": [
{ "value": "United Arab Emirates", "data": "AE" },
{ "value": "United Kingdom", "data": "UK" },
{ "value": "United States", "data": "US" }
]
}
I am trying to return results for this autocomplete widget
https://www.devbridge.com/sourcery/components/jquery-autocomplete/
You can just create an anonymous object. To return the JSON as indicated in your question, it would be
public JsonResult GetCities(string query)
{
var data = new
{
query = "Unit",
suggestions = new[]
{
new { value = "United Arab Emirates", data = "AE" },
new { value = "United Kingdom", data = "UK" },
new { value = "United States", data = "US" }
}
};
return Json(data, JsonRequestBehavior.AllowGet);
}
Side note: Unsure of the purpose of the method parameter?
I hate to go full blown on this, but maybe create your own classes?
public class DataValuePair
{
public string Data {get;set;}
public string Value {get;set;}
}
public class SearchResult
{
public string Query {get;set;}
public List<DataValuePair> Suggestions {get;set;}
}
And now you can return a JSON Result
return Json(mySearchResult);
Answer from OP:
Figured it out, below is the code
public ActionResult GetCities(string query)
{
var obj = new CitySuggestion();
obj.suggestions.Add(new Suggestion { value = "test1", data = "test1" });
obj.suggestions.Add(new Suggestion { value = "test2", data = "test2" });
obj.suggestions.Add(new Suggestion { value = "test3", data = "test3" });
return Content(JsonConvert.SerializeObject(obj), "application/json");
}
public class CitySuggestion
{
public CitySuggestion()
{
suggestions = new List<Suggestion>();
}
public List<Suggestion> suggestions
{
get;
set;
}
}
public class Suggestion
{
public string value { get; set; }
public string data { get; set; }
}

How do deserialize a json object with a Map as one of its properties

I have been using jackson to deserialize successfully json objects and arrays, but this time I just can't wrap my head around how to approach deserialization for the following object. How can I, with Jackson or any other json parsing library, deserialize:
[
{
"name": "x",
"elements": {
"key1": {
"name": "a",
"type": "b"
},
"key2": {
"name": "a",
"type": "b"
}
}
},
{
"name": "y",
"elements": {
"key3": {
"name": "a",
"type": "b"
}
}
}
]
into a list, List<Test>, where Test is defined below?
public class Test {
public class Element {
public String name;
public String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public String name;
public Map<String, Element> elements;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Element> getElements() {
return elements;
}
public void setElements(Map<String, Element> elements) {
this.elements = elements;
}
}
Finally, my deserializing code:
public List<Test> test(final InputStream inputStream) {
List<Test> test = null;
try {
test = mapper.readValue(inputStream, new TypeReference<List<Test>>() { });
} catch (final IOException e) {
log.error("Unable to deserialize json",e);
}
return test;
}
If that is not possible, what object can I actually deserialize my json into? One thing I cannot know ahead of time is the name of the keys (key1, key2, key3 in the example).
It looks like this:
ObjectMapper mapper = new ObjectMapper();
List<Test> tests = mapper.readValue(jsonInput, new TypeReference<List<Test>>() { };
would do it. The only tricky part is that TypeReference, which is needed to pass generic type information. Other libs use similar approaches (GSON has TypeToken or such).

Deserializing JSON object with unknown fields

The question is similar to Deserializing JSON with unknown fields but I would like to use the built in DataContractJsonSerializer instead.
So I have JSON data like that:
{
"known1": "foo",
"known2": "bar",
"more":{ "unknown12345": { "text": "foo", "label": "bar"},
"unknown67890": { "text": "foo","label":"bar"}
}
}
I thought I can do the datacontract like that:
[DataMember(Name = "known1")]
public string K1 { get; set; }
[DataMember(Name = "known2")]
public string K2 { get; set; }
[DataMember(Name = "more")]
public Dictionary<string,TwoStringMembersClass> More { get; set; }
And the TwoStringMembersClass is just this:
[DataContract(Name = "TwoStringMembersClass ")]
public class TwoStringMembersClass
{
[DataMember(Name = "text")]
public string Text { get; set; }
[DataMember(Name = "label")]
public string Label { get; set; }
}
But what seems to work in JSON.Net doesn't seem to work that easy with the native JSON parser. In ReadObject() I get an ArgumentException, probably because of the Dictionary.
Any idea what's the best solution how to make this work ?
Thanks in advance.
The DataContractJsonSerializer does not support deserializing Dictionary<TKey, TValue> from an object notation in JSON. It only supports treating a dictionary as an array. Hence the JSON needed to deserialize into the types you have defined should look like this:-
{
"known1": "foo",
"known2": "bar",
"more":[{ "Key": "unknown12345", "Value": { "text": "foo", "label": "bar"} },
{ "Key": "unknown67890", "Value": { "text": "foo","label":"bar"} }
]
}
If the schema of the incoming JSON can't be altered then you are not going to be able to use the DataContractJsonSerializer.