Converting simple Json to Complex Object in c# - c#

My Json is
{
Id: 1,
Name:'Alex',
ConnectedObjectName:'Obj',
ConnectedObjectId: 99
}
I want this JSON to be converted to the following object
Class Response
{
int Id,
string Name,
ConnectedObject Obj
}
Class ConnectedObject
{
string COName,
int COId
}
Is there a way to achieve this using DataContractJsonSerializer

Most serializers want the object and the data to share a layout - so most json serializers would want ConnectedObjectName and ConnectedObjectId to exist on the root object, not an inner object. Usually, if the data isn't a good "fit" for what you want to map it into, the best approach is to use a separate DTO model that matches the data and the serializer, then map from the DTO model to the actual model you want programatically, or using a tool like auto-mapper.
If you used the DTO approach, just about any JSON deserializer would be fine here. Json.NET is a good default. DataContractJsonSerializer would be way way down on my list of JSONserializers to consider.

To expand on what Marc Gravell has said, most JSON serializers would expect your JSON to look like the following, which would map correctly to your classes:
{
"Id": 1,
"Name": "Alex",
"Obj" : {
"COName": "Obj",
"COId": 99
}
}
The way to get around this would be to read your JSON into an object that matches it, and then map it form that object to the object that you want:
Deserialize to this object:
class COJson {
public int Id;
public string Name;
public string ConnectedObjectName;
public int ConnectedObjectId;
}
Then map to this object:
class Response {
public int Id;
public string Name;
public ConnectedObject Obj;
}
class ConnectedObject {
public string COName;
public string COId;
}
Like this:
using(var stream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
var serializer = new DataContractJsonSerializer(typeof(COJson));
var jsonDto = (COJson)ser.ReadObject(stream);
var dto = new Response(){
Id = jsonDto.Id,
Name = jsonDto.Name,
Obj = new ConnectedObject(){
COName = jsonDto.ConnectedObjectName,
COId = jsonDto.ConnectedObjectId
}
};
return dto;
}

Related

Is there a way to deserialize only a single JSON field [duplicate]

So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

How can I serialize this Json using my model class?

I have having a problem how to get the empty list and define the properties and set the values in a static method.
FYI : I am also using the same properties id and parentID in another payload that is not a List..
//Here is the json I have
[
{
"id": 1,
"parentId": 4
}
]
//Here is my model class, my static method "Payload" and the properties of Json
public class Model
{
public int id { get; set; }
public int parentId { get; set; }
public static Model Payload()
{
return new Model
{
//How to get define the List here and set the values
}
}
}
The json you have is a List so, with Newtonsoft.Json, you can deserialize to a list.
var myModels = JsonConvert.DeserializeObject<List<Model>>(jsonString);
If the json string is empty "[]", it will create an empty list (not sure if that's what you were asking about the empty list of Model).
To convert the list to string:
var stringPayload = JsonConvert.SerializeObject(myModels);
What is your goal exactly ? You just want to load a model from a JSON string ? If not, what is this list exactly ? I think you should look at this : https://www.newtonsoft.com/json
It's a very popular library for manipulate JSON and data model related to it.

C# deserialize JSON using JavaScriptSerializer.DeserializeObject

I am not a C# programmer, but rather playing with the language from time to time. I wonder, if I have a JSON string which I want to deserialize using JavaScriptSerializer.DeserializeObject, how could I do that. For instance, if I have a JSON:
{
"Name": "col_name2",
"Value": [
{
"From": 100,
"To": 200
},
{
"From": 100,
"To": 200
}
]
}
And I have that JSON string in a variable called sJson:
using System.Web.Script.Serialization;
...
JavaScriptSerializer jss = new JavaScriptSerializer();
Object json = jss.DeserializeObject(sJson);
and now how do I use this Object json variable?
Note: I already know how to do it using System.Web.Script.Serialization.Deserialize<T> method.
Look at this post for Davids Answer:
Deserialize json object into dynamic object using Json.net
You can put it into a dynamic (underlying type is JObject)
Then you can than access the information like this:
JavaScriptSerializer jss = new JavaScriptSerializer();
dynamic json = jss.DeserializeObject(sJson);
Console.WriteLine(json["Name"]); // use as Dictionary
I would prefer create a data transfer object (DTO) represent your JSON Structure as a c# class.
You could declare new custom classes for this specific case:
public class CustomClass
{
public string Name { get; set; }
public List<ValueClass> Value { get; set; }
}
public class ValueClass
{
public int From { get; set; }
public int To { get; set; }
}
Then deserialize directly to those classes (the deserializer will automatically map the correct properties):
JavaScriptSerializer jss = new JavaScriptSerializer();
CustomClass json = (CustomClass)jss.Deserialize(sJson, typeof(CustomClass));
Moreover if you have more than 1 items, this is easy as well:
List<CustomClass> json = (List<CustomClass>)jss.Deserialize(sJson, typeof(List<CustomClass>));

Read specific value from JSON in C#

So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

Manipulate Values of Stringfied values on C#

I have a below code that used JSON.stringify to the object then passed it on POST method (Please see below Javascript code). I'm getting those values on the backend using C#. My problem is, how could I convert/manipulate/access the stringified values. Please see below C# code
Javascript:
var json_db = JSON.stringify(selectedDbInfo);
$.post("../FormActions/DatabaseChanges.aspx", { action: "savedb", orderNumber: orderNumber, selectedDb: json_db},
function (response) {
alert('ok');
});
C#:
var dbValue = c.Request.Params["selectedDb"];
below is the result value of dbValue
"[{\"dbname\":\"BASINS\",\"distance\":\"0\"},{\"dbname\":\"BROWNFIELD\",\"distance\":\"0.5\"},{\"dbname\":\"BRS\",\"distance\":\"0\"}]"
You need to parse the JSON into a .NET array or List.
Many use json.NET for this: http://james.newtonking.com/json
At a push you could use some string manipulation to populate your objects one by one, but I wouldn't recommend that.
There are many samples here on SO.
if you're just want to convert it dictionary look here:
How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?
However, there's a built in mechanism in ASP.NET MVC that serializes automatically your json param to predefined objects at your convenient.
You may define a class having the fields like dbname and distance as properties. Then you may deserialize the json string dbValue into a list of that type using NewtonSoft.Json. Please see the code below:
var list = JsonConvert.DeserializeObject<List<RootObject>>(dbValue);
foreach (var item in list)
{
Console.WriteLine(string.Format("dbname: {0}, distance: {1}", item.dbname, item.distance));
}
Ans the definition of RootObject is as simple as you guess:
public class RootObject
{
public string dbname { get; set; }
public string distance { get; set; }
}
Create a custom serializable data contract class, say DatabaseDistance, with following properties:
[DataMember(Name = "dbname")]
private string name;
[DataMember(Name = "distance")]
private double distance;
and use following method for deserialization:
public static T FromJSON<T>(string jsonValue, IEnumerable<Type> knownTypes)
{
//validate input parameters here
T result = default(T);
try
{
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(jsonValue)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), knownTypes);
result = (T)serializer.ReadObject(stream);
}
}
catch (Exception exception)
{
throw new Exception("An error occurred while deserializing", exception);
}
return result;
}
pass list of your objects as type parameter

Categories

Resources