I have the following C# class:
public RuleCondition(string field,
Operator @operator,
RightValueExpression rightValueExpression)
{
_operator = @operator;
_field = field;
_rightValueExpression = rightValueExpression;
}
public RightValueExpression ValueExpression => _rightValueExpression;
public string Field => _field;
public Operator Operator => _operator;
}
public sealed class RightValueExpression
{
private readonly bool _relativeToBaseline;
private readonly double _value;
private readonly RightOperator _operator;
private readonly PercentOrAbsolute _isPercent;
public RightValueExpression(bool relativeToBaseline,
RightOperator @operator,
double value,
PercentOrAbsolute isPercent)
{
_isPercent = isPercent;
_operator = @operator;
_value = value;
_relativeToBaseline = relativeToBaseline;
}
public PercentOrAbsolute IsPercent => _isPercent;
public RightOperator Operator => _operator;
public double Value => _value;
public bool RelativeToBaseline => _relativeToBaseline;
}
public enum Operator
{
GreaterThan,
EqualTo,
LessThan,
GreaterThanEqualTo,
LessThanEqualTo
}
public enum RightOperator
{
Plus,
Minus,
Times,
DividedBy
}
public enum PercentOrAbsolute
{
Percent,
Absolute
}
When serialized to Json using Json.Net, I get the following:
var ruleCondition = new RuleCondition("Min", Operator.GreaterThan, new RightValueExpression(relativeToBaseline: true, RightOperator.Plus, 50, PercentOrAbsolute.Percent));
var json = JsonConvert.SerializeObject(ruleCondition);
Json:
{
"ValueExpression": {
"IsPercent": 0,
"Operator": 0,
"Value": 50.0,
"RelativeToBaseline": true
},
"Field": "Min",
"Operator": 0
}
All fine, however deserializing using Json.Net
var des = JsonConvert.DeserializeObject<RuleCondition>(json);
RightValueExpression
in RuleCondition is always null.
Do I need a custom deserializer here?
You can implement custom JsonConverter:
class RuleConditionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(RuleCondition));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
var @operator = (Operator)jo["Operator"].Value<int>();
var field = jo["Field"].Value<string>();
var isPercent = (PercentOrAbsolute)jo["ValueExpression"]["IsPercent"].Value<int>();
var rigthOperator = (RightOperator)jo["ValueExpression"]["Operator"].Value<int>();
var value = jo["ValueExpression"]["Value"].Value<double>();
var relativeToBaseline = jo["ValueExpression"]["RelativeToBaseline"].Value<bool>();
RuleCondition result = new RuleCondition(field, @operator, new RightValueExpression(relativeToBaseline, rigthOperator, value, isPercent));
return result;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Then you can use it during deserialization:
var des = JsonConvert.DeserializeObject<RuleCondition>(json, new RuleConditionConverter());
If you can live with a public setter on ValueExpression
property, you can avoid the specialized converter:
public class RuleCondition
{
public RuleCondition(string field,
Operator @operator,
RightValueExpression rightValueExpression)
{
ValueExpression = rightValueExpression;
Field = field;
Operator = @operator;
}
public RightValueExpression ValueExpression { get; set; }
public string Field { get; }
public Operator Operator { get; }
}
Alternatively you can rename the ValueExpression
property to RightValueExpression
:
public class RuleCondition
{
public RuleCondition(string field,
Operator @operator,
RightValueExpression rightValueExpression)
{
RightValueExpression = rightValueExpression;
Field = field;
Operator = @operator;
}
public RightValueExpression RightValueExpression { get; }
public string Field { get; }
public Operator Operator { get; }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.