D
D
dmitry84722016-11-22 18:49:02
JSON
dmitry8472, 2016-11-22 18:49:02

How to prevent object deserialization with Json.Net?

I need to get an object from a Json file with the following structure

{
"start" : 1,
"finish": 2,
"template" : 3
}

Here is my C# class:
public sealed class ORequest
    {
        public ORequest() { }

        [JsonProperty("start")]
        public long? start { get; set; }

       [JsonProperty("finish")]
        public long? finish { get; set; }

        [JsonProperty("template")]
       public int? template { get; set; }
    }

I create an object of class ORequest :
ORequest outRequest = JsonConvert.DeserializeObject<ORequest>(message, new JsonSerializerSettings { 
    NullValueHandling = NullValueHandling.Ignore,  
    MissingMemberHandling = MissingMemberHandling.Ignore
 });

But the deserialization is performed even if I put the following code in the message:
{
"sta" : 1,
"fini": 2,
"temp" : 3
}

As a result, an outRequest object will be created where all fields will be null.
How to make JsonConvertDeserilize return null for invalid fields in Json file

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Nemiro, 2016-11-22
@dmitry8472

Try Required :

[JsonProperty(PropertyName = "start", Required = Required.Always)]
public long? start { get; set; }

Or check the value of the key field (or fields), if the value is null , consider that the deserialization did not produce results ( outRequest = null ).
A key field is a field that is always present and cannot be null .
If there is nothing to catch on, then you can go through everyone:
if (!outRequest.start.HasValue && !outRequest.finish.HasValue && !outRequest.template.HasValue)
{
  outRequest = null;
}

In theory, if key fields use a type other than Nullable (for example, long instead of long? ), or together with the Required.Always attribute , then an exception should be thrown during deserialization if the required fields in the data are not found. An exception can be caught ( try-catch ) and thus understand that the incoming data is incorrect.
You can also make a custom converter - JsonConverter , but this can be a difficult decision, in terms of "energy costs" :-)
[JsonConverter(typeof(ORequestConverter))]
public sealed class ORequest
{
  [JsonProperty("start")]
  public long? start { get; set; }

  [JsonProperty("finish")]
  public long? finish { get; set; }

  [JsonProperty("template")]
  public int? template { get; set; }
}

public class ORequestConverter : JsonConverter
{

  public override bool CanWrite
  {
    get
    {
      return false;
    }
  }

  public override object ReadJson
  (
    JsonReader reader, 
    Type objectType, 
    object existingValue, JsonSerializer serializer
  )
  {
    if (reader.TokenType == JsonToken.Null)
    {
      return null;
    }

    var target = (ORequest)Activator.CreateInstance(objectType);

    serializer.Populate(reader, target);

    if (!target.start.HasValue && !target.finish.HasValue && !target.template.HasValue)
    {
      // необходимые поля не найдены или имеют значение null
      // возвращаем null
      return null;
    }

    return target;
  }

  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
    throw new NotImplementedException();
  }

  public override bool CanConvert(Type objectType)
  {
    throw new NotImplementedException();
  }

}

V
Vyacheslav Zolotov, 2016-11-22
@SZolotov

JsonIgnore attribute?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question