@dmitry8472

Как запретить десериализацию объекта с Json.Net?

Мне необходимо получить объект из Json файла следующей структуры
{
"start" : 1,
"finish": 2,
"template" : 3
}


Вот мой C# класс:
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; }
    }


Я создаю объект класса ORequest :
ORequest outRequest = JsonConvert.DeserializeObject<ORequest>(message, new JsonSerializerSettings { 
    NullValueHandling = NullValueHandling.Ignore,  
    MissingMemberHandling = MissingMemberHandling.Ignore
 });


Но десериализация выполняется, даже если я подам в message следующий код:
{
"sta" : 1,
"fini": 2,
"temp" : 3
}


В итоге создастся объект outRequest где все поля будут null.
Как сделать так, чтобы при неверных полях в файле Json JsonConvertDeserilize возвращал null
  • Вопрос задан
  • 362 просмотра
Решения вопроса 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
Попробуйте Required:

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

Либо проверяйте значение ключевого поля (или полей), если значение null, считайте что десериализация не дала результатов (outRequest = null).

Ключевое поле - это поле, которое присутствует всегда и не может иметь значение null.

Если зацепиться не за что, то можно и по всем пройтись:

if (!outRequest.start.HasValue && !outRequest.finish.HasValue && !outRequest.template.HasValue)
{
  outRequest = null;
}

По идее, если у ключевых полей использовать тип отличный от Nullable (например, long вместо long?), либо совместно с атрибутом Required.Always, то при десериализации должно выбрасываться исключение, если нужные поля в данных не будут найдены. Исключение можно перехватывать (try-catch) и таким образом понять, что входящие данные неверные.

Еще можно сделать пользовательский конвертер - JsonConverter, но это может быть сложным решением, в плане «энергозатрат» :-)

[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();
  }

}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@SZolotov
Asp.net core, MAUI,WPF,Qt, Avalonia
Атрибут JsonIgnore?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы