I work with an api, that returns a json formatted resultset of a database query.
I have an equivalent object or "model" for the results.
What is the best way to convert the json string into a list of this object?
Of course there are many threads about this, but no one fits my needs properly.
One of the solutions I've found was this:
var jobj = (JObject)JsonConvert.DeserializeObject(json);
var items = jobj.Children()
.Cast<JProperty>()
.Select(j => new
{
ID = j.Name,
Topic = (string)j.Value["Topic_ID"],
Moved = (string)j.Value["Moved_ID"],
Subject = (string)j.Value["subject"],
})
.ToList();
This seems pretty close to what I need. I need to be able to map the keys/values to the appropriate object attributes, which DOES already exist. So maybe you only need to change a few things to make it work for my object?
PS: I'm using Newtonsoft. Any solution for .NET or Newtonsoft or if needed any other library would be great!
I have recently been consuming data from a WebApi and i have been using the following code to convert the json object to an object to work with:
using (var client = new HttpClient())
{
var response = client.GetAsync(apiUri).Result;
// For single objects.
MyObject data = response.Content.ReadAsAsync<MyObject>().Result;
// For an array of objects
IEnumerable<MyObject> data = response.Content.ReadAsAsync<IEnumerable<MyObject>>().Result;
}
Hope this helps.
OK, so you have something like this:
public class MyObject
{
public int ID {get; set;}
public string Topic {get; set;}
public string Subject {get; set;}
}
And you want to instantiate an array of MyObjects with the properties coming from your JSON?
In that case you're just a bout there - you're currently creating a dynamic object with the same properties as MyObject, right? So all you need to do is create an actual MyObject instead:
.Select(j => new **MyObject()**
{
ID = j.Name,
Topic = (string)j.Value["Topic_ID"],
Moved = (string)j.Value["Moved_ID"],
Subject = (string)j.Value["subject"]
})
Note that if your json property names exactly match your C# ones (including case), you can do this as a one-liner with NewtonSoft: http://www.newtonsoft.com/json/help/html/SerializingJSON.htm. But to use that method you'd have to have an intermediate C# class to match your JSON, and then automap (or manually convert) those to MyObjects. Or you'd have to make sure your json and c# properties match exactly. But you're already very close to a quicker (though some would argue less elegant) solution.
Why aren't you deserializing the json into the object type directly? you can do it like this...
var obj = (YourType)JsonConvert.DeserializeObject(
json,
typeof(YourType),
new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto,
MissingMemberHandling=MissingMemberHandling.Ignore
});
or am I missing something in the question?
Related
Currently I am receiving an array of objects from a database.
object [] sqlResultData = DatabaseCall.Result();
This array of objects needs to be matched to class variables like this
CClassOfVars classVar = new CClassOfVars();
classVar.myProperty = sqlResultData[0];
classVar.myProperty1 = sqlResultData[1];
What i wish to do is pass the list of propertys on the class in order to a function and have the mapping from the object array occur automatically based on the order.
For example:
Method defined like this
FillData(object [] databaseValues, IList<object>())
Called like this
CClassOfVars classVar = new CClassOfVars();
object [] sqlResultData = DatabaseCall.Result();
FillData(sqlResultData, new List<object>(){classVar.myProperty,classVar.myProperty1});
The FillData function would hopefully type cast and set the values of myProperty and myProperty1 to the values in array locations of 0,1 etc...
Something like this
FillData(object [] databaseValues, IList<object> mapMe)
{
for (int i = 0; i < mapMe.Count; i++)
{
mapMe[i] = CastToTheCorrectType(mapMe[i], databaseValues[i]);
}
}
Cast to the correct type could look like this?? I took from here: cast object with a Type variable
public T CastToTheCorrectType<T>(T hackToInferNeededType, object givenObject) where T : class
{
return givenObject as T;
}
How can i pass a list of different object types to all have there values modified and assigned within a different function?
The matter you asking about is dark and difficult to be implemented through just a function. There are frameworks out there dealing with object relational mapping. If it is an option, install and learn some OR/M. If not ... well, there might be some dirty way.
You can use the JSON.NET library to do the heavy lifting for you. It's super easy to use and install through Nuget. My point is as follows.
Construct an anonymous object. Use the property names of the original object.
Fill it with the data from the object array. Spin a loop over the object array...
Serialize the anonymous object.
Deserialize the JSON string into the target type.
At this point, JSON.NET will handle property mapping for you.
List item
E.g. if your target type is Person you might do this:
var x = new
{
FirstName = String.Empty,
LastName = String.Empty
};
var persons = new List<Person>(sqlResultData.Length);
foreach (var record in sqlResultData)
{
x.FirstName = record[0];
x.LastName = record[1];
var s = JsonConvert.SerializeObject(x)`
var personX = JsonConvert.Deserialize<Person>(s);
persons.Add(person);
}
I need to pass a Json object to an API, but the API requires the Json properties to have a double label of sorts, such as:
{
"name:id":"1234"
}
However, using Newtonsoft.Json.Linq, I can't get this to format the label exactly. Here is what I've tried so far (which throws an error)
dynamic json= new JObject();
json.name.id = "1234";
Doing
json.id = "1234";
Works just fine. I have also tried
json.name = new JProperty("id", "1234");
Which also throws an error. I have also tried hard coding the json file as a single string and converting that to a JObject, which also threw an error. Is what I'm trying to do possible or am I missing something? Is there another Json package I could use that would support what I want to do?
Use JObject's string indexer notation.
dynamic json = new JObject();
json["name.id"] = "1234";
Since the json is essentially built as a key/value pair, using a string indexer can allow you to overcome atypical property names.
There multiple ways to achieve that.
You can use JsonProperty attribute and specify the property name as name:id like:
class MyClass
{
[JsonProperty("name:id")]
public string Name_Id { get; set; }
}
and then you can do:
MyClass obj = new MyClass();
obj.Name_Id = "1234";
var strJson = JsonConvert.SerializeObject(obj);
and you will get back:
{"name:id":"1234"}
I'm matching about 90 properties from a nested JSON-Object to a model class using dynamics and JObject.Parse:
dynamic json = JObject.Parse(JsonObjectAsString);
return new Foo() {
prop1 = json.summer.temperature,
prop2 = json.winter.temperature,
...
prop100 = json.autumn.temperature
}
This is very slow, but only on the first run. On a second run, a new JSON-Object is fetched (same structure but different values), and this one is assigned to the corresponding model properties in no time.
Why is that? What can I do to speed up the first run?
Edit: I've already set the build type to "Release".
You can parse your JSON object direct to model using newtonsoft nuget package.
var objData = JsonConvert.DeserializeObject<MyData>(yourjsondata);
You can get your model class from json data from http://json2csharp.com/
You can convert using dynamic object as well
var objData = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);
Or without specifying model calss
var objData = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
I am developing a windows 8 app, and i have some javascript that stores a serialized object into roaming settings, i.e:
var object = [{"id":1}, {"id":2}]
roamingSettings.values["example"] = JSON.stringify(object);
I also i have a c# part to the application (for running a background task), that needs to read that JSON, and turn it into an object so i can iterate over it. And this is where i am having some issues, i am using JSON.NET to do the work, but every thing i turn turns up with an error:
// this looks like "[{\"id\":1},{\"id\":2}]"
string exampleJSON = roaming.Values["example"].ToString();
// dont know if this is correct:
List<string> example = JsonConvert.DeserializeObject<List<string>>(exampleJSON );
That give an error of:
Error reading string. Unexpected token: StartObject. Path '[0]', line 1, position 2.
So i am at a loss of what to do, i have been working on it for last few hours, and i am quite unfamiliar with c#, so resorting to the help of stackoverflow ;D
Thanks in advance for any help :)
Andy
Json.Net has a nice method DeserializeAnonymousType. No need to declare a temporary class.
string json = "[{\"id\":1},{\"id\":2}]";
var anonymous = new []{new{id=0}};
anonymous = JsonConvert.DeserializeAnonymousType(json,anonymous);
foreach (var item in anonymous)
{
Console.WriteLine(item.id);
}
You can even use the dynamic keyword
dynamic dynObj = JsonConvert.DeserializeObject(json);
foreach (var item in dynObj)
{
Console.WriteLine(item.id);
}
You are trying to parse your JSON array into a List of strings, which doesn't work. The JSON object you provide is actually a list of objects containing an integer property called 'id'.
Perhaps try creating a class (say, MyClass) with just that property, and deserialize into List.
Your json containts a collection of objects with an id property, something like this:
class IdObject {
public int id { get; set; }
}
You could then do:
JsonConvert.DeserializeObject<List<IdObject>>(exampleJSON);
Because the IdObject class has a property id to match your json serialized value, it will be mapped back.
Let's say I have an object MyObject that looks like this:
public class MyObject
{
int ObjectID {get;set;}
string ObjectString {get;set;}
}
I have a list of MyObject and I'm looking to convert it in a json string with a stringbuilder. I know how to create a JavascriptConverter and create a json string by passing a list and having the converter build the string but in this particular case I'm looking to avoid the overhead and go straight to a json string with a foreach loop on the list like this:
StringBuilder JsonString = new StringBuilder();
foreach(MyObject TheObject in ListOfMyObject)
{
}
I've tried to use this method by appending with commas and quotes but it hasn't worked out (yet).
Thanks for your suggestions.
I've done something like before using the JavaScript serialization class:
using System.Web.Script.Serialization;
And:
JavaScriptSerializer jss = new JavaScriptSerializer();
string output = jss.Serialize(ListOfMyObject);
Response.Write(output);
Response.Flush();
Response.End();
3 years of experience later, I've come back to this question and would suggest to write it like this:
string output = new JavaScriptSerializer().Serialize(ListOfMyObject);
One line of code.
For me, it worked to use Newtonsoft.Json:
using Newtonsoft.Json;
// ...
var output = JsonConvert.SerializeObject(ListOfMyObject);
I would avoid rolling your own and use either:
System.Web.Script.JavascriptSerializer
or
JSON.net
Both will do an excellent job :)
why reinvent the wheel? use microsoft's json serialize or a 3rd party library such as json.NET
I prefer using linq-to-json feature of JSON.NET framework. Here's how you can serialize a list of your objects to json.
List<MyObject> list = new List<MyObject>();
Func<MyObject, JObject> objToJson =
o => new JObject(
new JProperty("ObjectId", o.ObjectId),
new JProperty("ObjectString", o.ObjectString));
string result = new JObject(new JArray(list.Select(objToJson))).ToString();
You fully control what will be in the result json string and you clearly see it just looking at the code. Surely, you can get rid of Func<T1, T2> declaration and specify this code directly in the new JArray() invocation but with this code extracted to Func<> it looks much more clearer what is going on and how you actually transform your object to json. You can even store your Func<> outside this method in some sort of setup method (i.e. in constructor).
You could return the value using
return JsonConvert.SerializeObject(objName);
And send it to the front end
If you are using WebApi, HttpResponseMessage is a more elegant way to do it
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, ListOfMyObject);
}