Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用json.net在序列化期间合并两个对象?_C#_Json_Serialization_Json.net - Fatal编程技术网

C# 使用json.net在序列化期间合并两个对象?

C# 使用json.net在序列化期间合并两个对象?,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我遇到了如下情况,有人能帮我实现以下目标吗 { "name":"...", "p1":"...", "p2":"..." } 例如,如果我拥有该类:- public class Sample { public String name {get;set;} public MyClass myclass {get;set;} } 我的Myclass如下所示: public class MyClass { public String p1 {get;set;}

我遇到了如下情况,有人能帮我实现以下目标吗

{
 "name":"...",
 "p1":"...",
 "p2":"..."
}
例如,如果我拥有该类:-

public class Sample
{
    public String name {get;set;}
    public MyClass myclass {get;set;}
}
我的
Myclass
如下所示:

public class MyClass
{
    public String p1 {get;set;}
    public String p2 {get;set;}
}
当我使用
Json.net
来序列化类示例的对象时,我得到了如下结果,它运行良好

{
 "name":"...",
 "myclass":
          {
            "p1":"...",
            "p2":"..."
           }
 }
这是正确的,但我想知道是否有可能获得如下所示的json字符串

{
 "name":"...",
 "p1":"...",
 "p2":"..."
}

您可以创建匿名对象并将其序列化:

var sample = new Sample { 
    name = "Bob", 
    myclass = new MyClass { 
                p1 = "x", 
                p2 = "y" 
              }};

string json = JsonConvert.SerializeObject(new { 
                 sample.name, 
                 sample.myclass.p1, 
                 sample.myclass.p2 
              });
结果

{"name":"Bob","p1":"x","p2":"y"}
但我建议您使用
Sample
类的默认序列化,或者创建将序列化为您的格式的类(即将
MyClass
属性移动到
Sample

更新:您可以使用自定义转换器,它将对象展平并将所有内部对象属性序列化为顶级对象属性:

public class FlattenJsonConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, 
        JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        if (t.Type != JTokenType.Object)
        {
            t.WriteTo(writer);
            return;
        }

        JObject o = (JObject)t;
        writer.WriteStartObject();
        WriteJson(writer, o);
        writer.WriteEndObject();
    }

    private void WriteJson(JsonWriter writer, JObject value)
    {
        foreach (var p in value.Properties())
        {
            if (p.Value is JObject)
                WriteJson(writer, (JObject)p.Value);
            else
                p.WriteTo(writer);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
       object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return true; // works for any type
    }
}
用法:

string json = JsonConvert.SerializeObject(sample, new FlattenJsonConverter());
或者,如果仅对一种类型需要此行为,则可以将匿名类型创建隐藏到自定义转换器中:

public class SampleJsonConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, 
        object value, JsonSerializer serializer)
    {
        Sample sample = (Sample)value;
        JToken t = JToken.FromObject(new { 
                      sample.name, 
                      sample.myclass.p1, 
                      sample.myclass.p2 
                   });

        t.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Sample);
    }
}

谢谢你的帮助,伙计。使用
CustomConverters
有什么方法可以做到这一点吗?我认为当property类有更多属性时,上面的代码将不方便。谢谢,伙计,我检查后会通知你。