首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用System.Text.Json内联JSON结构

如何用System.Text.Json内联JSON结构
EN

Stack Overflow用户
提问于 2022-09-06 03:31:16
回答 2查看 129关注 0票数 1

我在寻找与C#的json: "inline"标记相当的System.Text.Json

例如,在C#中有以下类结构:

代码语言:javascript
复制
class Outer{
    public string Hello;
    public Inner TheInner;
}

class Inner{
    public string Earth;
    public string Moon;
}

我希望序列化和反序列化的JSON文本是

代码语言:javascript
复制
{
   "Hello" : "example_value_01",
   "Earth" : "example_value_02",
   "Moon" : "example_value_03"
}

在Golang中,我可以通过以下结构定义来实现这一点

代码语言:javascript
复制
type Outer struct{
    Hello string
    TheInner Inner `json: "inline"`
}

type Inner struct{
   Earth string
   Moon string
}

但是,在C#的System.Text.Json中,我找不到一种合适的方法来做到这一点。

EN

回答 2

Stack Overflow用户

发布于 2022-09-06 05:24:18

此解决方案使用自反,类内的字符串项数独立,内部类名称也独立,只要您必须尊重它的属性或字段:

代码语言:javascript
复制
public class Outer
{
    public string? Hello;
    public Inner? TheInner { get; set; }
}

public class Inner
{
    public string? World1;
    public string? World2;
    public string? World3;
}

使用嵌套类的程序:

代码语言:javascript
复制
        var json= "{\"Hello\": \"hello\",\"World1\":\"world1\", \"World2\": \"world2\", \"World3\": \"world3\"}"; 
        var ou = deserialize(json);

        json = serialize(ou);

这些方法序列化和反序列化:

代码语言:javascript
复制
        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;
        }
票数 0
EN

Stack Overflow用户

发布于 2022-09-06 11:16:54

要在c#中访问它,根本不需要任何自定义类,可以使用字典

代码语言:javascript
复制
var dict = new Dictionary<string, string> {
                           {"Hello","example1"},
                           {"World","example2"}
                           };
                           
var json= System.Text.Json.JsonSerializer.Serialize(dict,new JsonSerializerOptions { WriteIndented = true});    

结果

代码语言:javascript
复制
{
  "Hello": "example1",
  "World": "example2"
}

但是,如果您想让它成为一种困难的方式,那么使用Newtonsoft.Json就容易多了,因为Text.Json几乎所有东西都需要一个自定义序列化程序。

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73616409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档