【问题标题】:Replacing an array item based on a property in the item根据项中的属性替换数组项
【发布时间】:2018-10-23 10:06:10
【问题描述】:

我在外部文件中有以下 JSON:

{
    "Name": "Service Provider",
    "Categories": [
        {
            "Name": "Identity",
            "Mandatory": false
        },
        {
            "Name": "Contat Information",
            "Mandatory": false
        },
        {
            "Name": "Service Fields",
            "Mandatory": false
        },
        {
            "Name": "Addresses",
            "Mandatory": false
        },
        {
            "Name": "Bank Accounts",
            "Mandatory": false
        }
    ]
}

如果我想替换,例如,“身份”类别在内存中看起来像这样:

{
    "Name": "Identity",
    "Mandatory": true,
    ...
}

我可以这样写:

JObject jObject = return JsonConvert.DeserializeObject<JObject>(File.ReadAllText(path));

// "GetNewIdentity()" gets a JObject representing the new "Identity" JSON shown above
jObject["Categories"][0] = GetNewIdentity();

问题是我在写代码的时候需要知道改什么类别。如果我只在运行时知道要更改哪个类别怎么办?

这就是为什么我想使用其Name 属性在数组中找到要替换的类别。我试过以下代码:

// "name" comes from a different place.
result["Categories"].Single(c => c["Name"].Equals(name)) = GetNewIdentity();

但是因为我试图将值分配给返回值而不是变量,所以我收到以下错误:

赋值的左边必须是变量、属性或 索引器

我还希望在替换后保留类别的顺序。我怎样才能做到这一点?


注意:

我没有或可以有代表 JSON 的 POCO 类。

【问题讨论】:

  • 你有可以反序列化这个 JSON 的类吗?
  • Modifying JSON(第一个搜索结果)
  • “我怎样才能做到这一点?” - 究竟是什么?通常您会反序列化、更改值然后序列化 json。什么是输入数据?这个 json 是文件、字符串还是什么?更改值后应该是什么?
  • 我肯定会去创建 POCO 课程,除非课程设计不合适
  • @Sinatr 请查看我对问题所做的更改,如果还不够清楚,请告诉我。

标签: c# json linq json.net


【解决方案1】:

这是一个示例,您可以如何做到这一点。您需要的是访问您想要的属性并替换它的值。

void Main()
{
    JObject jObject = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(path));
    JObject newCategory = new JObject();
    newCategory.Add("Name", "Identity");
    newCategory.Add("Mandatory", "false");
    newCategory.Add("NewProp", "Yes");
    ReplaceCategoryValue(jObject, "Identity", newCategory);

    Console.WriteLine(jObject.ToString());
}

void ReplaceCategoryValue(JObject jObject, string categoryName, JObject newCategory)
{
    JToken categories = jObject["Categories"];
    JObject targetCategory = categories.Children<JObject>().FirstOrDefault(x => x.Property("Name").Value.ToString() == categoryName);
    targetCategory.Replace(newCategory);
}

【讨论】:

  • 谢谢!此代码以属性为目标,而我想以包含该属性的对象为目标。这意味着,此代码替换了“名称”属性的值,而不是包含“名称”属性的对象 - 类别本身。
  • 啊抱歉误解了你的目标。我仍然不确定搜索的条件是什么,但请检查更新的答案。我认为您正在寻找 Replace 方法。
  • 您的代码运行良好,您正确理解了问题。非常感谢。
【解决方案2】:

我仍然不明白您为什么不定义 POCO。这里看看这个。 这是你的 POCOS

public class MyRootObject
{
    public string Name { get; set; }
    public List<Category> Categories { get; set; }
}

public class Category
{
    public string Name { get; set; }
    public bool Mandatory { get; set; }
}

这就是你使用它的方式

var rootObject = JsonConvert.DeserializeObject<MyRootObject>(Resource.Json);
//name comes from somewhere else like in the question
var identity = rootObject.Categories.Single(c => c.Name == name);
identity.Mandatory = GetNewIdentity();

【讨论】:

  • 我不能为此使用 POCO 课程,因为这是我的前辈所说的。 :)
  • 如果老年人永远是对的,我们仍然会认为地球是平的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
  • 2020-06-29
  • 2012-05-17
相关资源
最近更新 更多