Support distinguish between undefined and null in poco's
See original GitHub issueWe have the scenario that we need to know the difference of client send no/undefined property between client send property with null value in our mapped poco’s.
For this purpose we created the following classes.
[JsonConverter(typeof(OptionalConverter))]
public struct Optional<T> : OptionalConverter.IGenericAccess
{
bool _isValuePresent;
T _value;
public bool IsValuePresent
{
get => _isValuePresent;
set
{
_isValuePresent = value;
if(!value)
Value = default;
}
}
public T Value
{
get => _value;
set
{
_value = value;
_isValuePresent = true;
}
}
Type OptionalConverter.IGenericAccess.GenericType => typeof(T);
object OptionalConverter.IGenericAccess.Value
{
set => Value = (T)value;
get => Value;
}
public static implicit operator Optional<T>(T value) => new Optional<T> {Value = value};
public static explicit operator T(Optional<T> optional)
{
if(!optional.IsValuePresent)
throw new InvalidOperationException("The optional value is not preset");
return optional.Value;
}
public override string ToString()
{
if(!IsValuePresent)
return "{no value}";
if(Value == null)
return "{null}";
return Value.ToString();
}
}
public class OptionalConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var genericAccess = (IGenericAccess)value;
if (!genericAccess.IsValuePresent)
{
writer.WriteUndefined();
return;
}
serializer.Serialize(writer, genericAccess.Value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (existingValue == null)
existingValue = Activator.CreateInstance(objectType);
if (reader.TokenType != JsonToken.Undefined)
{
var genericAccess = (IGenericAccess)existingValue;
genericAccess.Value = serializer.Deserialize(reader, genericAccess.GenericType);
}
return existingValue;
}
public override bool CanConvert(Type objectType) => true;
public interface IGenericAccess
{
bool IsValuePresent { get; }
Type GenericType { get; }
object Value { set; get; }
}
}
This can be used like this:
class Result
{
public Optional<string> Name {get;set;}
public Optional<int?> Age {get;set;}
}
var result = JsonConvert.Desereialize<Result>("{age:null}");
Console.WriteLine(result.Name.IsValuePresent); // false
Console.WriteLine(result.Age.IsValuePresent); // true
I did not saw a different way of doing it, so I would ask if something like this wouldnt be a nice addition to Json.Net itself?!
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:11 (2 by maintainers)
Top Results From Across the Web
Null and Undefined in JavaScript
Undefined, on the other hand, means the variable has been declared, but its value has not been assigned. What is Null? We have...
Read more >Undefined Vs Null in JavaScript
1. Undefined means a variable has been declared but has yet not been assigned a value. Null is an assignment value. It can...
Read more >JavaScript — What's the difference between Null & ...
null is an assigned value. It means nothing. · undefined means a variable has been declared but not defined yet. · null is...
Read more >Difference Between Null and Undefined
Null. Null is used to represent an intentional absence of value. It represents a variable whose value is undefined. · Undefined. It represents...
Read more >Undefined vs Null - Javascript
The data type of undefined is undefined whereas that of null is object. We can find the datatypes of both undefined and null...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Thanks for your answer! But I think you misunderstood what I want to to. My problem is not the serialization side.
I have an webservice which accepts inputs like this.
and
With a mapping like this:
(Strong simplified case) The first one means. Update only the Name Property and leave Age unchanged. The second means Update Name and set Age to null (unset).
For this case I need to distinguish if
Age=undefined
andAge=null
which I think is not possible with Json.NET out of the box. This is why I suggested such a type like in my post above.Yes, I understood what you wanted and your solution works well with deserialization. I was facing the same problem. And I also want to handle the serialization as well. Btw, I have done it by inheriting DefaultContractResolver