您无法修改
JsonElement
,它是完全不可变的。相反,您必须将其反序列化为某个可变类型,例如
JsonNode
,对可变类型进行修改,然后重新序列化回
JsonElement
。以下方法可以实现这一点:
public static class JsonExtensions
{
public static JsonNode TryAddPropertyToArrayElements<TProperty>(this JsonNode node, string name, TProperty value)
{
if (node is JsonArray array)
foreach (var obj in array.OfType<JsonObject>())
obj[name] = JsonSerializer.SerializeToNode(value);
return node;
}
public static JsonElement TryAddPropertyToArrayElements<TProperty>(this JsonElement element, string name, TProperty value) =>
element.ValueKind == JsonValueKind.Array
? JsonSerializer.SerializeToElement(JsonSerializer.Deserialize<JsonNode>(element)!.TryAddPropertyToArrayElements(name, value))
: element;
public static object? TryAddPropertyToArrayElements<TProperty>(this object? obj, string name, TProperty value) =>
obj switch
{
JsonElement e => e.TryAddPropertyToArrayElements(name, value),
JsonNode n => n.TryAddPropertyToArrayElements(name, value),
null => null,
_ => throw new ArgumentException("Unexpected type ${obj}"),
};
}
然后你可以按照以下方式使用:
metas["key-1"] = metas["key-1"]?
.TryAddPropertyToArrayElements("newproperty", "test value");
示例演示 #1 here">这里。
显然,所有这些序列化都有些低效。为了避免额外的序列化,假设您通过反序列化生成了字典,您可以使用JsonSerializerOptions.UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode
">这个设置进行反序列化。此设置强制将声明为object
的类型反序列化为JsonNode
而不是JsonElement
:
var inputOptions = new JsonSerializerOptions
{
UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode,
};
var metas = JsonSerializer.Deserialize<Dictionary<string, object?>>(json, inputOptions)!;
如果你这样做,你将能够直接使用上面包含的方法
JsonExtensions.TryAddPropertyToArrayElements<TProperty>(this JsonNode node, string name, TProperty value)
来直接改变它的值。
注意事项:
JsonNode
和JsonSerializer.SerializeToElement()
是在.NET 6中引入的,所以如果你使用的是早期版本,你需要采用不同的方法。
演示fiddle #2
here。
Dictionary<string, object> metas
是如何构建的?是通过将 JSON 反序列化为Dictionary<string, object>
来构建的吗?例如:var metas = JsonSerializer.Deserialize<Dictionary<string, object>>(json)
? - dbcJsonSerializerOptions.UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode
进行反序列化。这样,你的字典值将变为可变的JsonNode
对象,而不是不可变的JsonElement
对象。 - dbcJsonSerializerOptions.UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode
进行反序列化。这样,你的字典值将变为可变的JsonNode
对象,而不是不可变的JsonElement
对象。 - undefined