I have an anonymous JSON object and I need to add a list of strings (parameter: productOptions) to it. I need to put them into a keyless JSON-array. How would I do that with anonymous types?
public static List<Product> getProductsByProductOptions(long salespartnerGroupID, string marktCode, long producttypeGroupID, long productvalueGroupID, long deviceGroupID, List<string> productOptions)
{
RestRequest request = newRestRequest("getProductsByProductOptions");
var jsonObj = new
{
input = new
{
spbgid = salespartnerGroupID,
code = marktCode,
producttypegid = producttypeGroupID,
productvaluegid = productvalueGroupID,
devicegid = deviceGroupID,
productOptions = new { item = productOptions }
},
};
IRestResponse response = GetResponseAndSerialize(jsonObj, request);
BaseProduct myDeserializedClass = JsonConvert.DeserializeObject<BaseProduct>(response.Content);
return myDeserializedClass.#return.item;
}
I need the JSON to be like this:
"input": {
"spbgid": 3797,
"code": "xxx",
"producttypegid": 5239,
"productvaluegid": 0,
"devicegid": 4030,
"productOptions": {
"item": [
"SCREEN_PROTECTOR", "REPLACEMENT"
]
}
}
I am not sure why but using the RestSharp.JsonSerializer instead of JsonConvert fixed the problem. The anonymous object seemingly works just fine.
Related
Currently i am using unity to post comments that get saved in a firebase RTDB.
here is the posting code:
Comment NewComment = new Comment("User1", "Great App!");
Dictionary<string, System.Object> childUpdates = new
Dictionary<string, System.Object>();
childUpdates["NewUpdate2"] = NewComment.ToDict();
_database.GetReference("DumbData").UpdateChildrenAsync(childUpdates);
which works well and posts the data to Firebase
For reference here is the Comment Class.
[System.Serializable]
public class Comment
{
public Comment(string Name,string Content)
{
this.Name = Name;
this.Content = Content;
}
public Dictionary<string,System.Object> ToDict()
{
Dictionary<string, System.Object> result = new Dictionary<string, System.Object>();
result["Name"] = this.Name;
result["Content"] = this.Content;
return result;
}
public string Name;
public string Content;
}
and the firebase registers the data received correctly.
but then when receiving the data, i would do
var dataSnapShot = await _database.GetReference("DumbData").GetValueAsync();
var Results = dataSnapShot.GetRawJsonValue();
var temp= JsonUtility.FromJson<Dictionary<string, Comment>>(Results)
but the thing is the FromJSON function returns Nulls everywhere , although the JSON is received correctly matching the structure on Firebase, for reference, the Results variable above looks like this:
{"NewUpdate":{"Content":"Great App!","Name":"User1"},"NewUpdate2":{"Content":"Great App!","Name":"User2"}}
so that's where i am stuck, i cannot deseriazlize the response back to be able to use it.
JsonUtility is very limited with nested objects, dictionaries, etc.
I'll recommend you to use another library for handling JSON serialize and deserialize, you can use Newtonsoft library for example, or use my own JsonManager (the repo includes and example of how it works and how to use it).
Newtonsoft:
Serialize:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
// {
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
// }
Deserialize:
string json = #"{
'Name': 'Bad Boys',
'ReleaseDate': '1995-4-7T00:00:00',
'Genres': [
'Action',
'Comedy'
]
}";
Movie m = JsonConvert.DeserializeObject<Movie>(json);
string name = m.Name;
// Bad Boys
So in your particular case that deserialize is not working, you should do something like:
Dictionary<string, Comment> temp = JsonConvert.DeserializeObject<Dictionary<string, Comment>>(json);
I have no problem deserializing a single json object
string json = #"{'Name':'Mike'}";
to a C# anonymous type:
var definition = new { Name = ""};
var result = JsonConvert.DeserializeAnonymousType(json, definition);
But when I have an array:
string jsonArray = #"[{'Name':'Mike'}, {'Name':'Ben'}, {'Name':'Razvigor'}]";
I am stuck.
How can it be done?
The solution is:
string json = #"[{'Name':'Mike'}, {'Name':'Ben'}, {'Name':'Razvigor'}]";
var definition = new[] { new { Name = "" } };
var result = JsonConvert.DeserializeAnonymousType(json, definition);
Of course, since result is an array, you'll access individual records like so:
string firstResult = result[0].Name;
You can also call .ToList() and similar methods on it.
You can deserialize to dynamic object by this.
dynamic result = JsonConvert.DeserializeObject(jsonArray);
One approach is to put an identifier in your JSON array string.
This code worked for me:
var typeExample = new { names = new[] { new { Name = "" } } };
string jsonArray = #"{ names: [{'Name':'Mike'}, {'Name':'Ben'}, {'Name':'Razvigor'}]}";
var result = JsonConvert.DeserializeAnonymousType(jsonArray, typeExample);
I am trying to parse a json and populate these values into an object with DataContractJsonSerializer. Having no luck with this yet.
The json is -
{
"0": [
547,
541,
507,
548,
519,
0
],
"1": [
573,
504
]
}
I have tried the following code:
try
{
string json = #"""0"":[547,541,507,548,519,0],""1"":[573,504]";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractSerializer(typeof(MyClass));
var jsonParsed = seraializer.ReadObject(memStream);
}
}
catch(Exception ex)
{
}
Always getting an exception that the data is invalid at the root. But online json validators say this is a valid json.
MyClass -
[DataContract]
public class MyClass
{
[DataMember]
public Dictionary<string, List<int>> values { get; set; }
}
Thanks Patrick for providing me a working solution with Newtonsoft. But just to learn , I want to see what am I doing wrong with DataContractJsonSerializer. The code below gives me no exception, but I am not getting any values after the parsing is complete.
string json = #"{""0"":[547,541,507,548,519,0],""1"":[573,504]}";
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>));
var jsonParsed = seraializer.ReadObject(memStream);
}
You should use Dictionary<string, List<int>> as the type to deserialize to. You also need to use the right serializer (DataContractSerializer is for XML, DataContractJsonSerializer for JSON):
var seraializer = new DataContractJsonSerializer(typeof(Dictionary<string, List<int>>), new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true });
var jsonParsed = seraializer.ReadObject(memStream);
Or for JSON.NET:
var x = JsonConvert.DeserializeObject<Dictionary<string, List<int>>>(json);
I have the following variable of type {Newtonsoft.Json.Linq.JArray}.
properties["Value"] {[
{
"Name": "Username",
"Selected": true
},
{
"Name": "Password",
"Selected": true
}
]}
What I want to accomplish is to convert this to List<SelectableEnumItem> where SelectableEnumItem is the following type:
public class SelectableEnumItem
{
public string Name { get; set; }
public bool Selected { get; set; }
}
I am rather new to programming and I am not sure whether this is possible. Any help with working example will be greatly appreciated.
Just call array.ToObject<List<SelectableEnumItem>>() method. It will return what you need.
Documentation: Convert JSON to a Type
The example in the question is a simpler case where the property names matched exactly in json and in code. If the property names do not exactly match, e.g. property in json is "first_name": "Mark" and the property in code is FirstName then use the Select method as follows
List<SelectableEnumItem> items = ((JArray)array).Select(x => new SelectableEnumItem
{
FirstName = (string)x["first_name"],
Selected = (bool)x["selected"]
}).ToList();
The API return value in my case as shown here:
{
"pageIndex": 1,
"pageSize": 10,
"totalCount": 1,
"totalPageCount": 1,
"items": [
{
"firstName": "Stephen",
"otherNames": "Ebichondo",
"phoneNumber": "+254721250736",
"gender": 0,
"clientStatus": 0,
"dateOfBirth": "1979-08-16T00:00:00",
"nationalID": "21734397",
"emailAddress": "sebichondo#gmail.com",
"id": 1,
"addedDate": "2018-02-02T00:00:00",
"modifiedDate": "2018-02-02T00:00:00"
}
],
"hasPreviousPage": false,
"hasNextPage": false
}
The conversion of the items array to list of clients was handled as shown here:
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
JObject result = JObject.Parse(responseData);
var clientarray = result["items"].Value<JArray>();
List<Client> clients = clientarray.ToObject<List<Client>>();
return View(clients);
}
I can think of different method to achieve the same
IList<SelectableEnumItem> result= array;
or (i had some situation that this one didn't work well)
var result = (List<SelectableEnumItem>) array;
or use linq extension
var result = array.CastTo<List<SelectableEnumItem>>();
or
var result= array.Select(x=> x).ToArray<SelectableEnumItem>();
or more explictly
var result= array.Select(x=> new SelectableEnumItem{FirstName= x.Name, Selected = bool.Parse(x.selected) });
please pay attention in above solution I used dynamic Object
I can think of some more solutions that are combinations of above solutions. but I think it covers almost all available methods out there.
Myself I use the first one
using Newtonsoft.Json.Linq;
using System.Linq;
using System.IO;
using System.Collections.Generic;
public List<string> GetJsonValues(string filePath, string propertyName)
{
List<string> values = new List<string>();
string read = string.Empty;
using (StreamReader r = new StreamReader(filePath))
{
var json = r.ReadToEnd();
var jObj = JObject.Parse(json);
foreach (var j in jObj.Properties())
{
if (j.Name.Equals(propertyName))
{
var value = jObj[j.Name] as JArray;
return values = value.ToObject<List<string>>();
}
}
return values;
}
}
Use IList to get the JArray Count and Use Loop to Convert into List
var array = result["items"].Value<JArray>();
IList collection = (IList)array;
var list = new List<string>();
for (int i = 0; i < collection.Count; j++)
{
list.Add(collection[i].ToString());
}
I need to create a Json object dynamically by looping through columns.
so declaring an empty json object then add elements to it dynamically.
eg:
List<String> columns = new List<String>{"FirstName","LastName"};
var jsonObj = new {};
for(Int32 i=0;i<columns.Count();i++)
jsonObj[col[i]]="Json" + i;
And the final json object should be like this:
jsonObj={FirstName="Json0", LastName="Json1"};
[TestFixture]
public class DynamicJson
{
[Test]
public void Test()
{
dynamic flexible = new ExpandoObject();
flexible.Int = 3;
flexible.String = "hi";
var dictionary = (IDictionary<string, object>)flexible;
dictionary.Add("Bool", false);
var serialized = JsonConvert.SerializeObject(dictionary); // {"Int":3,"String":"hi","Bool":false}
}
}
I found a solution very similar to DPeden, though there is no need to use the IDictionary, you can pass directly from an ExpandoObject to a JSON convert:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
foo.Test = true;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
and the output becomes:
{ "FirstName":"John", "LastName":"Doe", "Active":true }
You should use the JavaScriptSerializer. That can Serialize actual types for you into JSON :)
Reference: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
EDIT: Something like this?
var columns = new Dictionary<string, string>
{
{ "FirstName", "Mathew"},
{ "Surname", "Thompson"},
{ "Gender", "Male"},
{ "SerializeMe", "GoOnThen"}
};
var jsSerializer = new JavaScriptSerializer();
var serialized = jsSerializer.Serialize(columns);
Output:
{"FirstName":"Mathew","Surname":"Thompson","Gender":"Male","SerializeMe":"GoOnThen"}
Using dynamic and JObject
dynamic product = new JObject();
product.ProductName = "Elbow Grease";
product.Enabled = true;
product.StockCount = 9000;
Console.WriteLine(product.ToString());
// {
// "ProductName": "Elbow Grease",
// "Enabled": true,
// "StockCount": 9000
// }
Or how about:
JObject obj = JObject.FromObject(new
{
ProductName = "Elbow Grease",
Enabled = true,
StockCount = 9000
});
Console.WriteLine(obj.ToString());
// {
// "ProductName": "Elbow Grease",
// "Enabled": true,
// "StockCount": 9000
// }
https://www.newtonsoft.com/json/help/html/CreateJsonDynamic.htm