this is the class to create my json object
public class RootObject
{
public string name { get; set; }
public string id { get; set; }
public string school { get; set; }
public List<object> details{ get; set; }
}
this is the way I'm creating a new object
var obj = new RootObject();
obj.name= "test";
obj.id = "null";
obj.school = "something else";
Then I am serializing the object using JavaScriptSerializer (this is working fine)
I need to add an array to this list of object "details" to get something like this:
{
"name ":"test",
"id":null,
"school ":"something else",
"details":["details1","detail2"]
}
I tried to add as string or element by element but without success. How can I solve this?
I strongly suggest you just use Json.NET:
obj.details = new List<object>
{
"details1", "details2"
};
Then, JsonConvert.SerializeObject(obj, Formatting.Indented) gives:
{
"name": "test",
"id": "null",
"school": "something else",
"details": [
"details1",
"details2"
]
}
You need to initialize the List:
obj.details = new List<object>();
Then to add data:
obj.details.Add("Details1");
obj.details.Add("Details2");
Related
I want to get data from json file correctly. The json data file I modeled for this is as follows:
{
"Free title 1":[
{
"Subject": "a1",
"Relation": "a2"
},
{
"Subject": "b1",
"Relation": "b2"
}
],
"Another free title":[
{
"Subject": "z1",
"Relation": "z2"
},
{
"Subject": "y1",
"Relation": "y2"
}
],
"Unordered title":[
{
"Subject": "x1",
"Relation": "x2"
},
{
"Subject": "w1",
"Relation": "w2"
}
]
}
This is how I create an object class:
public class _Infos_
{
public List<_Info_> Infos { get; set; }
}
public class _Info_
{
public string Subject { get; set; }
public string Relation { get; set; }
}
And finally I'm trying to get the data in a method like this:
var js = JsonConvert.DeserializeObject<_Infos_>(File.ReadAllText("__FILE_PATH__"));
foreach (var j in js.Infos)
{
MessageBox.Show(j.Subject);
}
I get the error that js is empty. Here I want to get Free title 1, Another free title and Unordered title in a list. Of course, these titles will be constantly changing. Afterwards, I want to get the Subject and Relation data under these titles. But I have no idea how to get it.
This data structure is a dictionary of collections of _Info_s. You need to deserialize it to Dictionary<string, List<_Info_>>.
Here are System.Text.Json and Json.net examples:
var d = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, List<_Info_>>>(json);
var d2 = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, List<_Info_>>>(json);
Your class definition is a little wrong.
You can use online tools "json to c#" to generate the correct classes.
like this one: https://json2csharp.com
Your "root" of your json for example does not contain an array in your json. The property "Free title 1":[..] is an array, so your root needs a property with the name FreeTitle1 and it has to be an array/list.
public class Root
{
[JsonProperty("Free title 1")]
public List<TitleInfo> FreeTitle1 { get; set; }
[JsonProperty("Another free title")]
public List<TitleInfo> AnotherFreeTitle { get; set; }
[JsonProperty("Unordered title")]
public List<TitleInfo> UnorderedTitle { get; set; }
}
public class TitleInfo
{
public string Subject { get; set; }
public string Relation { get; set; }
}
If your object members have dynamic names, you can also manually deserialize the object, e.g. using the general type JObject. E.g.
JObject obj = JObject.Parse(File.ReadAllText("__FILE_PATH__"));
JObject implements IEnumerable<KeyValuePair<string, JToken>> over which you can iterate.
Each member will then have JToken Value, which is a JArray in this case, which you can cast to a List of your type.
foreach (var groups in obj)
{
var infos = groups.Value.ToObject<List<_Info_>>();
// .. loop over infos
}
I have the following code :
public City[] Cities { get; set; }
In City class, I have two properties
public string Name { get; set; }
public string Code { get; set; }
When a request comes that has this Cities field empty I would like to hide this with Newtonsoft.
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public City[] Cities { get; set; }
But this code I have tried does not work because Cities is not null, but empty and the request always has the two properties in this array.
How should I use Newtonsoft in this case? Is there any additional check for the objects here needed?
You should use Conditional Property Serialization in JSON.NET. I think you are going to ignore this property if it's empty or null so, inside the class contains Cities properties add this method:
// ignore a property on a condtion
public bool ShouldSerializeCities() => Cities != null && Cities.Count > 0;
Update 1:
As #DavidG mentioned the workaround above won't ignore string fields (Name and Code) if they are null or empty. For making that happen you need to make use of DefaultValue:
Define JsonConvert settings like this:
var settings = new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
};
Use DefaultValue attribute over your desiarred field/properties:
public class City
{
[DefaultValue("")]
public string Name
{
get;
set;
}
[DefaultValue("")]
public string Code
{
get;
set;
}
}
Serialize your object with the settings you created above:
JsonConvert.SerializeObject(obj, settings) ;
For example, if your object looks like this:
var obj = new Foo{
Cities = new [] {
new City() {Name = "A", Code = ""}
, new City() {Name = "B", Code = "C"}
, new City(){Name = "", Code = ""}
}
};
The result will be:
{
"Cities": [
{
"Name": "A"
},
{
"Name": "B",
"Code": "C"
},
{}
]
}
I created a project on .NET Fiddle to see how it works.
If you don't like creating new settings, you still can use ShuldSerializeMemberName inside your City class:
public class City
{
public string Name{get;set;}
public bool ShouldSerializeName() => !string.IsNullOrEmpty(Name);
}
I would like to deserialize a json to object. The json is like below. But one property value maybe string or array, does anyone know how to handle this?
{
"name": "123", //Name
"properties": [
{
"propertyId": "Subject", // property id
"value": [
{
"entityId": "math", //entity id
"entityTypeId": "MATH" //entity type id
}
]
},
{
"propertyId": "Description",
"value": "Hello World."
}
]
}
The class is like below.
//The object
public class Content
{
public Content()
{
//Properties is List.
Properties = new List<Property>();
}
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "properties")]
public List<Property> Properties { get; set; }
}
public class Property
{
public Property()
{
Value = new List<Value>();
}
[JsonProperty(PropertyName = "propertyId")]
public string PropertyDefId { get; set; }
//Actually this property value can also be string, that's the problem.
[JsonProperty(PropertyName = "value")]
public List<Value> Value { get; set; }
}
//Value object
public class Value
{
//Have to write comments.
[JsonProperty(PropertyName = "entityId")]
public string EntityId { get; set; }
//Have to write comments.
[JsonProperty(PropertyName = "entityTypeId")]
public string EntityTypeId { get; set; }
}
I've done this in Java with Gson liblary and it was like
JsonObject field = parser.parse(json).getElementAsJSONObject();
if (field.isPrimitive()) {
String text = field.asString();
} else if (field.isArray()) {
JSONArray array = field.asArray();
}
I wrote this code from my memory so not 100% reliable. I don't know any solution for C# though.
$.parseJSON will convert your string to the correct object even if the property type is different for two different properties.
http://jsfiddle.net/mdanielc/e0acsyp1/2/
var jsonString = '{"name": "123","properties": [{"propertyId": "Subject","value": [{"entityId":"math","entityTypeId": "MATH" }]},{"propertyId": "Description","value": "Hello World."}]}';
var jsonobj = $.parseJSON(jsonString);
alert(jsonobj.properties[0].value[0].entityId);
alert(jsonobj.properties[1].value);
});
I have Json string like below
{
"JsonValues":{
"id": "MyID",
"values": {
"value1":{
"id": "100",
"diaplayName": "MyValue1"
},
"value2":{
"id": "200",
"diaplayName": "MyValue2"
}
}
}
}
I want to convert Json string to below classes
class ValueSet
{
[JsonProperty("id")]
public string id
{
get;
set;
}
[JsonProperty("values")]
public List<Value> values
{
get;
set;
}
}
class Value
{
public string id
{
get;
set;
}
public string DiaplayName
{
get;
set;
}
}
My deserialization code is
JavaScriptSerializer js = new JavaScriptSerializer();
StreamReader sr = new StreamReader(#"ValueSetJsonString.txt");
string jsonString = sr.ReadToEnd();
var items = JsonConvert.DeserializeObject<ValueSet>(jsonString);
But I am getting null values after serialization, How i can solve this?
As others have already pointed out, the reason you are not getting the results you expect is because your JSON does not match the class structure that you are trying to deserialize into. You either need to change your JSON or change your classes. Since others have already shown how to change the JSON, I will take the opposite approach here.
To match the JSON you posted in your question, your classes should be defined like those below. Notice I've made the following changes:
I added a Wrapper class corresponding to the outer object in your JSON.
I changed the Values property of the ValueSet class from a List<Value> to a Dictionary<string, Value> since the values property in your JSON contains an object, not an array.
I added some additional [JsonProperty] attributes to match the property names in your JSON objects.
Class definitions:
class Wrapper
{
[JsonProperty("JsonValues")]
public ValueSet ValueSet { get; set; }
}
class ValueSet
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("values")]
public Dictionary<string, Value> Values { get; set; }
}
class Value
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("diaplayName")]
public string DisplayName { get; set; }
}
You need to deserialize into the Wrapper class, not the ValueSet class. You can then get the ValueSet from the Wrapper.
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;
Here is a working program to demonstrate:
class Program
{
static void Main(string[] args)
{
string jsonString = #"
{
""JsonValues"": {
""id"": ""MyID"",
""values"": {
""value1"": {
""id"": ""100"",
""diaplayName"": ""MyValue1""
},
""value2"": {
""id"": ""200"",
""diaplayName"": ""MyValue2""
}
}
}
}";
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;
Console.WriteLine("id: " + valueSet.Id);
foreach (KeyValuePair<string, Value> kvp in valueSet.Values)
{
Console.WriteLine(kvp.Key + " id: " + kvp.Value.Id);
Console.WriteLine(kvp.Key + " name: " + kvp.Value.DisplayName);
}
}
}
And here is the output:
id: MyID
value1 id: 100
value1 name: MyValue1
value2 id: 200
value2 name: MyValue2
http://json2csharp.com/
I found the above link incredibly helpful as it corrected my C# classes by generating them from the JSON that was actually returned.
Then I called :
JsonConvert.DeserializeObject<RootObject>(jsonString);
and everything worked as expected.
Did you check this line works perfectly & your string have value in it ?
string jsonString = sr.ReadToEnd();
if yes, try this code for last line:
ValueSet items = JsonConvert.DeserializeObject<ValueSet>(jsonString);
or if you have an array of json you can use list like this :
List<ValueSet> items = JsonConvert.DeserializeObject<List<ValueSet>>(jsonString);
good luck
Your data structure and your JSON do not match.
Your JSON is this:
{
"JsonValues":{
"id": "MyID",
...
}
}
But the data structure you try to serialize it to is this:
class ValueSet
{
[JsonProperty("id")]
public string id
{
get;
set;
}
...
}
You are skipping a step: Your JSON is a class that has one property named JsonValues, which has an object of your ValueSet data structure as value.
Also inside your class your JSON is this:
"values": { ... }
Your data structure is this:
[JsonProperty("values")]
public List<Value> values
{
get;
set;
}
Note that { .. } in JSON defines an object, where as [ .. ] defines an array. So according to your JSON you don't have a bunch of values, but you have one values object with the properties value1 and value2 of type Value.
Since the deserializer expects an array but gets an object instead, it does the least non-destructive (Exception) thing it could do: skip the value. Your property values remains with it's default value: null.
If you can: Adjust your JSON. The following would match your data structure and is most likely what you actually want:
{
"id": "MyID",
"values": [
{
"id": "100",
"diaplayName": "MyValue1"
}, {
"id": "200",
"diaplayName": "MyValue2"
}
]
}
Json Convert To C# Class = https://json2csharp.com/json-to-csharp
after the schema comes out
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
string myJSON = client.DownloadString("http://xxx/xx/xx.json");
var valueSet = JsonConvert.DeserializeObject<Root>(myJSON);
The biggest one of our mistakes is that we can't match the class structure with json.
This connection will do the process automatically. You will code it later ;) = https://json2csharp.com/json-to-csharp
that's it.
you have an unmatched jSon string, if you want to convert into a list, try this
{
"id": "MyID",
"values": [
{
"id": "100",
"diaplayName": "MyValue1",
},
{
"id": "200",
"diaplayName": "MyValue2",
}
]
}
This is possible too:
using System.Web.Helpers;
var listOfObjectsResult = Json.Decode<List<DataType>>(JsonData);
This takes the JsonElement and deserializes it to List of objects.
List<object> draftInvoices = JsonConvert.DeserializeObject<List<object>>(jsonDrafts.ToString());
Example:
[HttpPost]
[Route("CreateDraft")]
public async Task<IActionResult> CreateDraft([FromBody] JsonElement jsonDrafts)
{
List<object> draftInvoices = JsonConvert.DeserializeObject<List<object>>(jsonDrafts.ToString());
for (int i = 0; i < draftInvoices.Count; i++)
{
........
}
You may use Json.Net framework to do this.
Just like this :
Account account = JsonConvert.DeserializeObject<Account>(json);
the home page : http://json.codeplex.com/
the document about this : http://james.newtonking.com/json/help/index.html#
In my web app I'm using Newtonsoft.Json and I have following object
[Newtonsoft.Json.JsonObject(Title = "MyCar")]
public class Car
{
[Newtonsoft.Json.JsonProperty(PropertyName = "name")]
public string Name{get;set;}
[Newtonsoft.Json.JsonProperty(PropertyName = "owner")]
public string Owner{get;set;}
}
and I want serialize them with root name (class name). This is desired format using
{'MyCar':
{
'name': 'Ford',
'owner': 'John Smith'
}
}
I know that I can do that with anonymous object, but is any property or another way in Newtonsoft.Json library?
Use anonymous class
Shape your model the way you want using anonymous classes:
var root = new
{
car = new
{
name = "Ford",
owner = "Henry"
}
};
string json = JsonConvert.SerializeObject(root);
I found an easy way to render this out... simply declare a dynamic object and assign the first item within the dynamic object to be your collection class...This example assumes you're using Newtonsoft.Json
private class YourModelClass
{
public string firstName { get; set; }
public string lastName { get; set; }
}
var collection = new List<YourModelClass>();
var collectionWrapper = new {
myRoot = collection
};
var output = JsonConvert.SerializeObject(collectionWrapper);
What you should end up with is something like this:
{"myRoot":[{"firstName":"John", "lastName": "Citizen"}, {...}]}
You can easily create your own serializer
var car = new Car() { Name = "Ford", Owner = "John Smith" };
string json = Serialize(car);
string Serialize<T>(T o)
{
var attr = o.GetType().GetCustomAttribute(typeof(JsonObjectAttribute)) as JsonObjectAttribute;
var jv = JValue.FromObject(o);
return new JObject(new JProperty(attr.Title, jv)).ToString();
}
Sorry, my english is not that good. But i like to improve the upvoted answers.
I think that using Dictionary is more simple and clean.
class Program
{
static void Main(string[] args)
{
agencia ag1 = new agencia()
{
name = "Iquique",
data = new object[] { new object[] {"Lucas", 20 }, new object[] {"Fernando", 15 } }
};
agencia ag2 = new agencia()
{
name = "Valparaiso",
data = new object[] { new object[] { "Rems", 20 }, new object[] { "Perex", 15 } }
};
agencia agn = new agencia()
{
name = "Santiago",
data = new object[] { new object[] { "Jhon", 20 }, new object[] { "Karma", 15 } }
};
Dictionary<string, agencia> dic = new Dictionary<string, agencia>
{
{ "Iquique", ag1 },
{ "Valparaiso", ag2 },
{ "Santiago", agn }
};
string da = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
Console.WriteLine(da);
Console.ReadLine();
}
}
public class agencia
{
public string name { get; set; }
public object[] data { get; set; }
}
This code generate the following json (This is desired format)
{
"Iquique":{
"name":"Iquique",
"data":[
[
"Lucas",
20
],
[
"Fernando",
15
]
]
},
"Valparaiso":{
"name":"Valparaiso",
"data":[
[
"Rems",
20
],
[
"Perex",
15
]
]
},
"Santiago":{
"name":"Santiago",
"data":[
[
"Jhon",
20
],
[
"Karma",
15
]
]
}
}
string Json = JsonConvert.SerializeObject(new Car { Name = "Ford", Owner = "John Smith" }, Formatting.None);
for the root element use GlobalConfiguration.
A very simple approach for me is just to create 2 classes.
public class ClassB
{
public string id{ get; set; }
public string name{ get; set; }
public int status { get; set; }
public DateTime? updated_at { get; set; }
}
public class ClassAList
{
public IList<ClassB> root_name{ get; set; }
}
And when you going to do serialization:
var classAList = new ClassAList();
//...
//assign some value
//...
var jsonString = JsonConvert.SerializeObject(classAList)
Lastly, you will see your desired result as the following:
{
"root_name": [
{
"id": "1001",
"name": "1000001",
"status": 1010,
"updated_at": "2016-09-28 16:10:48"
},
{
"id": "1002",
"name": "1000002",
"status": 1050,
"updated_at": "2016-09-28 16:55:55"
}
]
}
Hope this helps!
Well, you can at least tell Json.NET to include the type name: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm . Newtonsoft.Json.JsonSerializer jser = new Newtonsoft.Json.JsonSerializer();
jser.TypeNameHandling = TypeNameHandling.Objects;
The type will be included at the beginning in the "$type" property of the object.
This is not exactly what you are looking for, but it was good enough for me when facing a similiar problem.
Writing a custom JsonConverter is another approach mentioned in similar questions. However, due to nature of how JsonConverter is designed, using that approach for this question is tricky, as you need to be careful with the WriteJson implementation to avoid getting into infinite recursion: JSON.Net throws StackOverflowException when using [JsonConvert()].
One possible implementation:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//JToken t = JToken.FromObject(value); // do not use this! leads to stack overflow
JsonObjectContract contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());
writer.WriteStartObject();
writer.WritePropertyName(value.GetType().Name);
writer.WriteStartObject();
foreach (var property in contract.Properties)
{
// this removes any property with null value
var propertyValue = property.ValueProvider.GetValue(value);
if (propertyValue == null) continue;
writer.WritePropertyName(property.PropertyName);
serializer.Serialize(writer, propertyValue);
//writer.WriteValue(JsonConvert.SerializeObject(property.ValueProvider.GetValue(value))); // this adds escaped quotes
}
writer.WriteEndObject();
writer.WriteEndObject();
}
I hope this help.
//Sample of Data Contract:
[DataContract(Name="customer")]
internal class Customer {
[DataMember(Name="email")] internal string Email { get; set; }
[DataMember(Name="name")] internal string Name { get; set; }
}
//This is an extension method useful for your case:
public static string JsonSerialize<T>(this T o)
{
MemoryStream jsonStream = new MemoryStream();
var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
serializer.WriteObject(jsonStream, o);
var jsonString = System.Text.Encoding.ASCII.GetString(jsonStream.ToArray());
var props = o.GetType().GetCustomAttributes(false);
var rootName = string.Empty;
foreach (var prop in props)
{
if (!(prop is DataContractAttribute)) continue;
rootName = ((DataContractAttribute)prop).Name;
break;
}
jsonStream.Close();
jsonStream.Dispose();
if (!string.IsNullOrEmpty(rootName)) jsonString = string.Format("{{ \"{0}\": {1} }}", rootName, jsonString);
return jsonString;
}
//Sample of usage
var customer = new customer {
Name="John",
Email="john#domain.com"
};
var serializedObject = customer.JsonSerialize();
[Newtonsoft.Json.JsonObject(Title = "root")]
public class TestMain
this is the only attrib you need to add to get your code working.