ignore null values while deserializing JSON in newtonsoft - c#

I have following json coming from server
{
"contactList":[{
"contactName":"Jhon",
"address":null,
"phone":null,
"contactId":99932
}]
}
now when i am deserializing using JsonConvert.DeserializeObject<Response>(content) i want following output
{
"contactList":[{
"contactName":"Jhon",
"contactId":99932
}]
}
i tried following code but its not working
JsonSerializerSettings jsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
this is my Contact model
public class Contact
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String address { set; get; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String phone { set; get; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String name { set; get; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String id { set; get; }
}
model of Response
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Response
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public IList<SignodeMSA.Model.Master.Contact> contactsList { get; }
}
and i am deserializing after fetching it from server
Response responseData = await Task.Run(() => JsonConvert.DeserializeObject<Response>(content, jsonSettings));

I think you need manually delete that properties from json string.
Maybe like this : How do I remove all null and empty string values from a json object?

Related

C# Parsing JSON using JObject.Parse to ignore missing fields

Is it possible to have JObject.Parse ignore missing fields?
From my example below you can see that I have declared a class Address and using JsonProperty to specifying alternate field names.
I have provided 3 examples, there are 3 JSON strings which have a slightly different structure, only Example 1 matches and returns an object, Examples 2 and 3 return a null because there is a missing field.
Is there a way to use other JsonProperty's to allow them to be ignored if not provided?
public class Address
{
[JsonProperty("flat_number")]
public string FlatNumber { get; set; }
[JsonProperty("house_number")]
public string HouseNumber { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
private static T TryParse<T>(string json) where T : new()
{
var jSchemaGenerator = new JSchemaGenerator();
const string license = "license";
License.RegisterLicense(license);
var jSchema = jSchemaGenerator.Generate(typeof(T));
var jObject = JObject.Parse(json);
return jObject.IsValid(jSchema) ? JsonConvert.DeserializeObject<T>(json) : default(T);
}
//Example 1 with house_number and flat_number
const string json = "{\"house_number\":\"40\",\"flat_number\":\"82\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
//Example 2 with house_number but not flat_number
//const string json = "{\"house_number\":\"40\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
//Example 3 with flat_number but not house_number
//const string json = "{\"flat_number\":\"82\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
var tryParse = TryParse<AddressTest>(json);
if (tryParse != null)
{
}
You can use JsonSerializerSettings to perform this operation. This will ignore your
missing members.
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
If you json contains some key/value pair as dynamic means you don't know if these key/value pairs is exist in json or not
If your objects are not fixed and data must be configurable then Newtonsoft.json has one feature that to be use here and that is [JsonExtensionData]. Read more
Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.
Now your house_number and flat_number will be collected in [JsonExtensionData] so you no need to handle missing fields anymore.
So your Address class will be
public class Address
{
[JsonExtensionData]
public IDictionary<string, JsonToken> extensionData { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
After a little more digging I found a JsonProperty that allows nulls to be ignored, by applying NullValueHandling = NullValueHandling.Ignore to both FlatNumber and HouseNumber all examples return an object. Therefore modifying the Address class as per my example below works in conjunction with my original code.
public class Address
{
[JsonProperty("flat_number", NullValueHandling = NullValueHandling.Ignore)]
public string FlatNumber { get; set; }
[JsonProperty("house_number", NullValueHandling = NullValueHandling.Ignore)]
public string HouseNumber { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}

Unable to get specific string from Json C#

This is how my json looks like:
I created the following code:
public class user
{
public string username { get; set; }
public int userid
{
get;
set;
}
public string red
{
get;
set;
}
public string acompaccompelted_setup
{
get;
set;
}
}
To get the data from URL I used the following code:
string url = "localhost/testingdata/file.json";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
string jsonValue = "";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
json = reader.ReadToEnd();
}
user listing = JsonConvert.DeserializeObject<user>(json);
Console.WriteLine(listing.username);
Console.ReadLine();
Unfortunately, I'm not able to get the value for the string "username". It returns an empty value. If I try to use :
List<user> items = JsonConvert.DeserializeObject<List<user>>(json);
Then I'm getting another error. If I call the:
Console.WriteLine(json);
Then I'm getting the complete list of JSON. But I want to extract the username only. I tried to follow steps given here https://www.c-sharpcorner.com/article/working-with-json-in-C-Sharp/ but with no success. What I'm doing wrong?
Define a wrapper UserInfo class to represent the whole object as follows:
class UserInfo
{
[JsonProperty(PropertyName = "user", NullValueHandling = NullValueHandling.Ignore)]
public User User { get; set; }
}
Define the User class as follows:
class User
{
[JsonProperty(PropertyName = "userName", NullValueHandling = NullValueHandling.Ignore)]
public string UserName { get; set; }
[JsonProperty(PropertyName = "userId", NullValueHandling = NullValueHandling.Ignore)]
public long UserId { get; set; }
[JsonProperty(PropertyName = "accompletedSetup", NullValueHandling = NullValueHandling.Ignore)]
public string AccompletedSetup { get; set; }
[JsonProperty(PropertyName = "accompletedInfo", NullValueHandling = NullValueHandling.Ignore)]
public AccompletedInfo AccompletedInfo { get; set; }
}
The accompletedInfo property is a complex object. So define a new class to represent it as follows:
class AccompletedInfo
{
}
Follow the same pattern for all the nested objects. i.e. define a class for each nested object with properties and name of the property in the JsonProperty attribute.
Then deserialize using JsonConvert as follows:
var user = JsonConvert.DeserializeObject<UserInfo>(json);
The object user now has all the properties as expected.

Deserialize nested, complex json object to just a string c#

I have JSON which looks like:
{
"name": "foo",
"settings": {
"setting1": true,
"setting2": 1
}
}
I know how to use json2csharp.com to create the C# classes to deserialize this. They looks like:
public class Settings
{
public bool settings1 { get; set; }
public int settings2 { get; set; }
}
public class RootObject
{
public string name { get; set; }
public Settings settings { get; set; }
}
but what I want is to simply deserialize it into
public class RootObject
{
public string name { get; set; }
public string settings { get; set; }
}
i.e., all of the "setting" JSON just needs to be saved as a string--the structure of that JSON is not consistent. How can that be done? Thanks!
You could use a JToken to capture your unknown settings during deserialization, then use a second property to allow you to access that JSON as a string if you need to.
Set up your class like this:
public class RootObject
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonIgnore]
public string Settings
{
get { return SettingsToken != null ? SettingsToken.ToString(Formatting.None) : null; }
set { SettingsToken = value != null ? JToken.Parse(value) : JValue.CreateNull(); }
}
[JsonProperty("settings")]
private JToken SettingsToken { get; set; }
}
Then deserialize as usual:
var root = JsonConvert.DeserializeObject<RootObject>(json);
The Settings property will contain the settings part of the JSON as a string. If you reserialize the object back to JSON then the settings will retain whatever structure it had before.
You can also change the Settings property to some other JSON string, as long as it is well-formed. (If it isn't, then an exception will be thrown immediately.)
Here is a round-trip demo: https://dotnetfiddle.net/thiaWk
Try using Newtonsoft.Json plus LINQ:
string jsonText = #"{
'name': 'foo',
'settings': {
'settings1': true,
'settings2': 1
}
}";
JObject jObj = JObject.Parse(jsonText);
var setting = jObj.Descendants()
.OfType<JProperty>()
.Where(p => p.Name == "settings")
.First()
.Value.ToObject<Settings>();
Try this:
public class RootObject
{
public string name { get; set; }
public Dictionary<string,object> settings { get; set; }
}
Fiddle:
https://dotnetfiddle.net/QN3nWL
I have just this solution:
public class RootObject
{
public string name { get; set; }
public Settings settings { get; set; }
public string strSettings { get; set; } <--------
}
and
var data= Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json);
data.strSettings = Newtonsoft.Json.JsonConvert.SerializeObject(data.settings);

Validating JSON Schema in C# - Is there a better method?

Currently I am building some functionality that takes an object (in my case a blog post) in JSON format and validates it meets the 'Post' schema before deserializing it into an object. This is my current solution -
{
const string rawPost = #"{
""userId"": 1,
""id"": 200,
""title"": ""hello"",
""body"": ""body""
}";
JSchemaGenerator generator = new JSchemaGenerator();
JSchema schema = generator.Generate(typeof(Post));
var isPost = IsValid(JObject.Parse(rawPost), schema);
if (isPost)
{
var post = JsonConvert.DeserializeObject<Post>(rawPost);
}
}
public static bool IsValid(JObject jObject, JSchema jSchema)
{
return jObject.IsValid(jSchema);
}
public class Post
{
public int userId { get; set; }
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
}
}
Currently I do not like the fact that my 'Post' object in this case has incorrectly cased properties and breaks normal conventions - Which means the object is not very reusable. Is there another way of achieving the same thing with Pascal Casing?
You could decorate the properties of your class with the NewtonSoft JsonProperty attribute, setting the PropertyName as follows:
using Newtonsoft.Json;
public class Post
{
[JsonProperty(PropertyName = "userId")]
public int UserId { get; set; }
[JsonProperty(PropertyName = "id ")]
public int Id { get; set; }
[JsonProperty(PropertyName = "title ")]
public string Title { get; set; }
[JsonProperty(PropertyName = "body ")]
public string Body { get; set; }
}
The JsonSerializer object will use these in its deserialization.
Edit: or as per the linked duplicate question

Deserialize JSON to Custom Class - Object is null

I have an AJAX call that sends the following JSON to my webservice:
{"Tags":["12","5","2"],"TargetId":"36946","TargetType":"Officer"}
Here's the webservice and custom class:
[WebMethod]
public string UpdateTags(string PostParameters)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
var tagData = serializer.Deserialize<TagData>(PostParameters);
// do some stuff with tagData
}
[Serializable]
[DataContract(Name = "PostParameters")]
public class TagData
{
[DataMember(Name = "TargetId")]
string TargetId { get; set; }
[DataMember(Name = "TargetType")]
string TargetType { get; set; }
[DataMember(Name = "Tags")]
List<int> Tags { get; set; }
}
Unfortunately, the properties of tagData are null. What am I not doing correctly?
Properties in TagData are not public. Make them public and it should work.
Also I would suggest using JSON.NET. It is faster.

Categories