【问题标题】:JSON Patch update nested objectJSON补丁更新嵌套对象
【发布时间】:2021-01-10 20:26:41
【问题描述】:

我一直在尝试使用 JSON Patch 在嵌套对象中使用替换值,但是我觉得我没有得到正确的表示法。任何想法应该是什么路径?

我在LINQPad 6 中创建了以下代码来证明它。

void Main()
{
    var patchTest = new PatchTest();
    patchTest.Create();
    patchTest.ToString().Dump("Before Patch");
    var patch = JsonConvert.DeserializeObject<JsonPatchDocument<Contact>>(
        @"[
    {
      ""op"": ""replace"",
      ""path"": ""/firstname"",
      ""value"": ""Benjamin""
    },
    {
      ""op"": ""replace"",
      ""path"": ""age"",
      ""value"": ""29""
    },
    {
      ""op"": ""replace"",
      ""path"": ""//Appointment//Name"",
      ""value"": ""fsdfdsf""
    },
]");
    patchTest.Patch(patch);
    patchTest.ToString().Dump("After Patch");
}

public class PatchTest
{
    public Contact Contact { get; set; }

    public PatchTest() { }

    public void Create()
    {
        Contact = new Contact
        {
            FirstName = "Walt",
            LastName = "Banks",
            Age = 20
        };
    }

    public void Patch(JsonPatchDocument<Contact> patch)
    {
        patch.Replace(e => e.Appointment, Contact.Appointment);
        patch.ApplyTo(Contact);
    }

    public override string ToString()
    {
        return $"{nameof(Contact)}: {Contact}";
    }
}

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public Appointment Appointment { get; set; }

    public override string ToString()
    {
        return $"{nameof(FirstName)}: {FirstName}, {nameof(LastName)}: {LastName}, {nameof(Appointment)}: {Appointment}";
    }
}


public class Appointment
{
    public string Name { get; set; }

    public override string ToString()
    {
        return $"{nameof(Name)}: {Name}";
    }
}

但是找不到名字

【问题讨论】:

    标签: c# json asp.net-core json-patch


    【解决方案1】:

    找不到约会名称的原因是因为您在创建Contact 时没有初始化Appointment。将Create 更改为:

    public void Create()
    {
        Contact = new Contact
        {
            FirstName = "Walt",
            LastName = "Banks",
            Age = 20,
            Appointment = new Appointment()
        };
    }
    

    现在在控制台应用程序中运行您的示例会产生以下输出:

    Before Patch
    Contact: FirstName: Walt, LastName: Banks, Age: 20, Appointment: Name:
    After Patch
    Contact: FirstName: Benjamin, LastName: Banks, Age: 29, Appointment: Name: fsdfdsf
    

    我将Contact.Age 添加到其ToString() 覆盖中,因为它丢失了。此外,单 / 和双 // 都在路径中工作。我猜你在试图找出问题所在时使用了后者。

    现在,由于您已经在 J​​SON 中定义了文档,因此您不需要定义另一个替换操作。您的Patch 方法可以简化为:

    public void Patch(JsonPatchDocument<Contact> patch)
    {
        patch.ApplyTo(Contact);
    }
    

    并且输出将与以前相同。相当于在代码中完成所有这些操作,而无需手动创建 JSON 文档,如下所示:

    public void Patch(Contact amendedContact)
    {
        var patch = new JsonPatchDocument<Contact>();
        patch.Replace(e => e.FirstName, amendedContact.FirstName);
        patch.Replace(e => e.Age, amendedContact.Age);
        patch.Replace(e => e.Appointment.Name, amendedContact.Appointment.Name);
        patch.ApplyTo(Contact);
    }
    

    这样称呼它:

    var amendedContact = new Contact
    {
        FirstName = "Benjamin",
        Age = 29,
        Appointment = new Appointment
        {
            Name = "fsdfdsf"
        }
    };
    
    patchTest.Patch(amendedContact);
    

    这又会产生您想要的输出。但是您仍然必须确保初始化嵌套属性,否则您将遇到原始问题。

    【讨论】:

      【解决方案2】:

      您正在尝试为未初始化的Appointment 上的Name 属性设置值。创建新实例时更新Contact类以初始化属性:

      public class Contact
      {
          public Contact()
          {
              Appointment = new Appointment();
          }
      
          ...
      }
      

      根据经验,您应该尝试初始化所有类似的属性,以确保其他类不会发生类似的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 2016-11-20
        • 1970-01-01
        相关资源
        最近更新 更多