system.text. json явно установить нулевые атрибуты, игнорируя неустановленные атрибуты при сериализации - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь сериализовать объект POCO в запрос на обновление.

Мои неустановленные значения сериализуются как нулевые, что приводит к их обновлению до нуля.

Если я установил IgnoreNullValues ​​в правда, это решает проблему. Однако тогда нет способа явно обновить атрибут до нуля.

Я думаю, что подход к решению этой проблемы состоит в создании настраиваемого нулевого объекта, который сериализуется в нулевое значение и игнорирует реальные нулевые значения. Это возможно? Как еще я могу решить эту проблему?

Изменить: добавлен пример объекта запроса POCO, который я пытаюсь сериализовать

internal class ContactCreateRequest
{
   [JsonPropertyName("contact")]
   public ContactEntity Contact { get; set; }
}

internal class ContactEntity
{
    public string CompanyName { get; set; }
    public DateTime? CreateDateTime { get; set; }
    public string CreateId { get; set; }
    public string Department { get; set; }
    public string DisplayName { get; set; }
    public string FirstName { get; set; }
    public string GoesBy { get; set; }
    public string Id { get; set; }
    public string JobTitle { get; set; }
    public DateTime? LastEditDateTime { get; set; }
    public string LastEditId { get; set; }
    public string LastName { get; set; }
    public string ParentId { get; set; }
    public string Title { get; set; }
    public string UpdateAction { get; set; }
}

Я бы хотел следующее

var request = new ContactCreateRequest
{
   Contact = new ContactEntity
   {
      LastName = "Jane",
      JobTitle = null,
      UpdateAction = "Update"
   }
}

{"contact": {"LastName": "Jane", "JobTitle": null, "UpdateAction": "Update"}}

... но, конечно, это не сработает, потому что все неустановленные поля также равны нулю, поэтому они обрабатываются так же, как JobTitle. Вот почему мне интересно, нужно ли мне использовать шаблон нулевого объекта, чтобы определить, что JobTitle должен быть установлен в нуль явно.

1 Ответ

0 голосов
/ 10 июля 2020

EDIT: из-за очень подходящего комментария к db c, я изменил значение «null» на «null_null», чтобы избежать проблем с обработкой фамилий «Null».

Вы Вы можете достичь своей цели, создав специальный преобразователь JSON, присвоив своим свойствам строки значение « null » "null_null" вместо null и используя параметр IgnoreNullValues. Сериализатор JSON проигнорирует все неинициализированные значения, а пользовательский преобразователь сериализует ваше "нулевое" "null_null" значение, как если бы оно было null. Если вам нужна аналогичная функциональность для других типов, например DateTime, вам необходимо добавить новый DateTime JsonConverter или создать JsonConverter, который является более общим c и может обрабатывать все возможные случаи. Возможно, это не идеальное решение, но оно работает.

Вот конвертер:

public class NullConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return reader.GetString();
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        if (value == "null_null") writer.WriteNullValue();
        else writer.WriteStringValue(value);
    }
}

Вы можете использовать его так:

var request = new ContactCreateRequest()
{
    Contact = new ContactEntity
    {
        LastName = "Jane",
        JobTitle = "null_null",   // initializing to a "null_null" string instead of null
        UpdateAction = "Update"
     }
};

Console.WriteLine(JsonSerializer.Serialize(request, new JsonSerializerOptions() { 
                        Converters = { new NullConverter()}, 
                        IgnoreNullValues = true})
                  );
...