我在寻找与C#的json: "inline"标记相当的System.Text.Json。
例如,在C#中有以下类结构:
class Outer{
public string Hello;
public Inner TheInner;
}
class Inner{
public string Earth;
public string Moon;
}我希望序列化和反序列化的JSON文本是
{
"Hello" : "example_value_01",
"Earth" : "example_value_02",
"Moon" : "example_value_03"
}在Golang中,我可以通过以下结构定义来实现这一点
type Outer struct{
Hello string
TheInner Inner `json: "inline"`
}
type Inner struct{
Earth string
Moon string
}但是,在C#的System.Text.Json中,我找不到一种合适的方法来做到这一点。
发布于 2022-09-06 05:24:18
此解决方案使用自反,类内的字符串项数独立,内部类名称也独立,只要您必须尊重它的属性或字段:
public class Outer
{
public string? Hello;
public Inner? TheInner { get; set; }
}
public class Inner
{
public string? World1;
public string? World2;
public string? World3;
}使用嵌套类的程序:
var json= "{\"Hello\": \"hello\",\"World1\":\"world1\", \"World2\": \"world2\", \"World3\": \"world3\"}";
var ou = deserialize(json);
json = serialize(ou);这些方法序列化和反序列化:
public Outer deserialize(string json)
{
var fieldhello = typeof(Outer).GetFields().First();
var propinner = typeof(Outer).GetProperties().First();
var subfieldsinner = typeof(Inner).GetFields().ToArray();
var document = JsonDocument.Parse(json);
JsonElement root = document.RootElement;
var outer = new Outer();
var inner = new Inner();
var innerstArr = subfieldsinner.Select(f => (field: f, value: root.TryGetProperty(f.Name, out var item) ? item.GetString() : null));
foreach(var p in innerstArr)
p.field.SetValue(inner, p.value);
string? hellost = root.TryGetProperty(fieldhello.Name, out var item) ? item.GetString() : null;
fieldhello.SetValue(outer, hellost);
propinner.SetValue(outer, inner);
return outer;
}
public string serialize(Outer outer)
{
var fieldhello = outer.GetType().GetFields().First();
var propinner = outer.GetType().GetProperties().First();
var inn = (Inner) propinner.GetValue(outer, null);
var subfieldsinner = inn.GetType().GetFields().ToArray();
using var ms = new MemoryStream();
using var writer = new Utf8JsonWriter(ms);
writer.WriteStartObject();
writer.WriteString(fieldhello.Name, (string?)fieldhello.GetValue(outer));
foreach(var f in subfieldsinner)
writer.WriteString(f.Name, (string?)f.GetValue(inn));
writer.WriteEndObject();
writer.Flush();
string json = Encoding.UTF8.GetString(ms.ToArray());
return json;
}发布于 2022-09-06 11:16:54
要在c#中访问它,根本不需要任何自定义类,可以使用字典
var dict = new Dictionary<string, string> {
{"Hello","example1"},
{"World","example2"}
};
var json= System.Text.Json.JsonSerializer.Serialize(dict,new JsonSerializerOptions { WriteIndented = true}); 结果
{
"Hello": "example1",
"World": "example2"
}但是,如果您想让它成为一种困难的方式,那么使用Newtonsoft.Json就容易多了,因为Text.Json几乎所有东西都需要一个自定义序列化程序。
using Newtonsoft.Json;
var json = SerializeOuterObj(obj, "TheInner");
obj = DeserializeOuterObj(json);
public string SerializeOuterObj(object outerObj, string innerObjectPropertyName)
{
var jsonParsed = JObject.FromObject(outerObj);
var prop = jsonParsed.Properties().Where(i => i.Name == innerObjectPropertyName).First();
prop.Remove();
foreach (var p in ((JObject)prop.Value).Properties())
jsonParsed.Add(p.Name, p.Value);
return jsonParsed.ToString();
}
public Outer DeserializeOuterObj(string json)
{
var jsonParsed = JObject.Parse(json);
var outer = jsonParsed.ToObject<Outer>();
outer.TheInner = jsonParsed.ToObject<Inner>();
return outer;
}https://stackoverflow.com/questions/73616409
复制相似问题