Default numeric value from JSON property with empty string - c#

I'm trying to deserialize a JSON string, which contains an empty string value for one property... that property should be parsed into a decimal property of the class...
public class myClass {
public decimal my_value { get; set; } = 0;
}
var json = "{ \"my_value\": \"\" }";
var data = JsonConvert.DeserializeObject<myClass>(json);
The issue is that data is coming back as a null object.
I've tried setting the property to be decimal?, and that does return an object, but my_value is null when I need it to default to 0.
I've also tried the following, but it returns a null object (using either decimal or decimal?)...
[System.ComponentModel.DefaultValue(0)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public decimal my_value { get; set; } = 0;
How can I set this up to default to a value of 0 if the JSON contains an empty string for the property?
Before anybody states it... yes, the easy answer is to not have an empty string property in the JSON, but there is nothing I can do about it

You need to set up your serialization settings to ignore null values.
the settings would look like this if you are using Newtonsoft. You can learn more here
var = jsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
}

Related

Why Newtonsoft's serializer can create json, which wouldn't be able to deserialize?

I've notice such strange thing. Why can such instance be serialized, instead of exception? Why do I get exception at the last command, the same option makes this json?
class Dto
{
[JsonProperty(Required = Required.Always)]
public List<string> Property { get; set; }
}
static void Main(string[] args)
{
var dto = new Dto
{
Property = null
};
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
var json = JsonConvert.SerializeObject(dto, settings);
JsonConvert.DeserializeObject<Dto>(json, settings);
}
The Required option for JsonPropertyAttribute is only applicable for deserialization. See https://www.newtonsoft.com/json/help/html/JsonPropertyRequired.htm.
Thus when you ignore null values in the settings, which applies to both serialization and deserialization, you allow it to be omitted when serialized - which also means that there will be nothing there to deserialize, hence the exception.
#fredrik's answer is not correct.
[JsonProperty(Required = Required.Always)] is applicable on both Serialization and Deserialization. If you want to ensure, try this code:
class MyClass
{
public int Id { get; set; }
[JsonProperty(Required = Required.Always)]
public string Data { get; set; } = "default";
}
var originObj = new MyClass() {Id = 12, Data = null};
var setting = new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore};
var jsn1 = JsonConvert.SerializeObject(originObj); //throws
Investigating the Newtonsoft source code we can find that it is just implementation.
It allows you to skip null value if there is NullValueHandling = NullValueHandling.Ignore on Serialization - Just open JsonSerializerInternalWriter Implementation and find CalculatePropertyValues method (then find ShouldWriteProperty condition).
But it ignores any settings and throws an exception if Property is marked as Required - Find EndProcessProperty here.
JsonConvert.DeserializeObject<Dto>(json, Settings);
Looks like a typo due to the capital S of Settings when it should be settings.

Decimal properties are serialized even are not populated

I had to generate some classes from an xsd file. The classes and properties are generated correct with xml serialization annotation. The problem is that the decimal properties of a class are serialized with Newtonsoft.Json even are not populated. I would like to serialize only the decimal properties that are properly populated. Amount is part of SaleMessage
For example:
class Amount
{
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal RequestedAmount;
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal CashBackAmount;
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal TipAmount;
}
//Usage
var amount = new Amount()
{
RequestedAmount = 12.0
}
Using this structure it will always serialize all the properties
like this
{"RequestedAmount":12.0,"CashBackAmount":0.0,"TipAmount":0.0}
Which is not the expected behaviour.
The question is how can I modify the serialization to not parse the not set properties
static string Serialize(SaleMessage saleMessage)
{
var serialize= JsonConvert.SerializeObject(saleToPoiMessage,
new StringEnumConverter(),
new IsoDateTimeConverter() { DateTimeFormat = DateTimeFormat });
return serialize;
}
Any help is appreciated :)
You can set the DefaultValueHandling setting to Ignore to suppress serialization of values that are equal to their default value.
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new StringEnumConverter(),
new IsoDateTimeConverter() { DateTimeFormat = DateTimeFormat }
},
DefaultValueHandling = DefaultValueHandling.Ignore
};
var json = JsonConvert.SerializeObject(saleMessage, settings);
Fiddle: https://dotnetfiddle.net/o32k0U
Since it's of type decimal primitive it will have some value by default. I think you need to implement the serializer utility Newtonsoft.Json uses - on your own. Where you will not include the decimal values of 0.0 (if this suits the business logic).
Another option is not to use the primitive class and then set up the property of removing null values while serializing. I believe you can set up this config parameter in Newtonsoft.
Check this: https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
In my case I changed the primitive types to nullable.
public decimal? CashBackAmount {get; set;}
This worked for me. I prefer the #Brian Rogers answer. :)

Json.net deserializer ignores non-null reference type properties

I have an object with a constructor, which sets all the properties to their default values, including some reference-type values:
class MySettings
{
public int Test1 { get; set; } // works well
public MyClass Test2 { get; set; } // stays at the default value
public MySettings()
{
this.Test1 = 123;
this.Test2 = new MyClass(1);
}
}
when I try to deserialize an object, the reference-type property (Test2) stays at the value, set in the constructor, but the value-type property (Test1) deserializes well.
_jsonSerializationSettings =
new JsonSerializerSettings
{
Formatting = Formatting.Indented,
};
var result = JsonConvert.DeserializeObject<MySettings>(jsonString, _jsonSerializationSettings);
If I comment setting of Test2 property in the constructor, it deserializes well too.
What am I doing wrong?
As per from documentation of Newtonsoft,
Json.NET Deserializer use ObjectCreationHandling.Auto as default which uses existing object if it has already been created.
If you want to create new object by Json.NET itself, you should use ObjectCreationHandling.Replace in JsonSerializerSettings which creates new object irrespective of whether object has already been created or not.
You can set ObjectCreationHandling setting in JsonSerializerSettings which you can use in your deserializing.
Your setting should be :
_jsonSerializationSettings =
new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ObjectCreationHandling = ObjectCreationHandling.Replace
};

How to refine json by remove null values properties and zero (0) value properties from the c# object

Scenario:
I have to send a Httpwebrequest and server demands it will accept only two values as Json format, I want to send one more request to another server and that demands one value at a time in Json format.
For above scenario I created a Class and provide all three properties like following
pubilc class MyClass
{
public string as { get; set;}
public int value { get; set;}
public string asd { get;s et;}
}
For the first HttpWebRequest, to the first server, I want to send only two properties from MyClass 'as' and 'asd' now I will serialize through JsonConvert function of NewtonSoft as following
MyClass class = new MyClass();
string json = JsonConvert.SerializeObject(class);
The above syntax will return json having 0 and null values properties, NewtonSoft provide the functions to remove the null value from Json but it can't remove the properties having value 0, or you can say if your property data type is int and there is no any value assigned than it assign 0 to those properties.
Syntax to remove Null properties from Json
string json = JsonConvert.SerializeObject(class, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
The above syntax will remove the null values during serialize the MyClass object.
Now Question how to remove properties from json if it has properties having 0.
You can try to define your int property as nullable:
public int? value { get; set;}
Just modify your expression
string json = JsonConvert.SerializeObject(
class,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }
);
as below,
string json = JsonConvert.SerializeObject(
class,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
}
);
Answer given by mgigirey accepted by me, Another solution which i did, I converted my Json into xml and removed the nodes having value 0 and again converted into Json. My solution is also working for me but it is bit lengthy and slower then Mgigirey answer.
So two answers are here, if you anyone want to go with my solution then see following.
//This line will remove the null as i earlier mentioned in my question.
string jsonStatus = JsonConvert.SerializeObject(myJson, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
//Create xml object by covnert json into xml
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
//Get the property name which have the value 0
var v = doc.GetElementsByTagName("value")[0];
//Remove the child node.
doc.DocumentElement.RemoveChild(v);
//Again convert into the json.
string jsonText = JsonConvert.SerializeObject(doc);

Newtonsoft.JSON Serialization Array, Object, or Null

I have some JSON that can be a List or null. How do I create a POCO for this JSON?
Here is an example array:
http://pastebin.com/qAZF2Ug9
Here is my POCO:
http://pastebin.com/hUtgyytc
How can I tell Newtonsoft.JSON to ignore the SalesLine object, if it is null?
You can specify the settings:
var settings = new Newtonsoft.Json.JsonSerializerSettings {
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore};
and use that in various serializer constructors and serialize calls.
Alternatively, IIRC it supports conditional serialization, i.e.
public bool ShouldSerializeFoo() { return Foo != null; }
// pairs to property Foo
Try to mark this property with JsonProperty attribute
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public SaleLines SaleLines { get; set; }

Categories