C# Newtonsoft Json序列化/反序列化嵌套属性

C# Newtonsoft Json序列化/反序列化嵌套属性,c#,json.net,json-deserialization,json-serialization,C#,Json.net,Json Deserialization,Json Serialization,我的班级结构如下 public class MainClass { public string MyStringValue {get;set;} public SecondClass MyClassValue {get;set;} } public class SecondClass { public string Value {get;set;} } 我设置了以下值: SecondClass secondClass = new SecondClass { Value

我的班级结构如下

public class MainClass
{
   public string MyStringValue {get;set;}
   public SecondClass MyClassValue {get;set;}
}

public class SecondClass
{
   public string Value {get;set;}
}
我设置了以下值:

SecondClass secondClass = new SecondClass
{
   Value = "Test"
}

MainClass mainClass = new MainClass
{
   MyStringValue = "String Value",
   MyClassValue = secondClass
}
当我序列化类“mainClass”时,我得到以下Json(这对我来说是绝对清楚的):

在某些情况下,我需要序列化为以下内容:

{
  "MyStringValue":"String Value",
  "MyClassValue": "Test"
}
子类的字段名始终为“Value”,如何做到这一点?
(对于相同的结构,我还需要一个反序列化程序)

上层json与后者不同。未经转换,无法将主类序列化为
{“MyStringValue”:“String Value”,“MyClassValue”:“Test”}

var resultObjet = new { 
     MyStringValue = mainClass.MyStringValue,
     MyClassValue = mainClass.SecondClass.MyClassValue
}

然后可以序列化它。

上面的json与后面的json不同。未经转换,无法将主类序列化为
{“MyStringValue”:“String Value”,“MyClassValue”:“Test”}

var resultObjet = new { 
     MyStringValue = mainClass.MyStringValue,
     MyClassValue = mainClass.SecondClass.MyClassValue
}

然后您可以序列化它。

为了实现这一点,您需要一个用于反序列化的新类。但是,对于序列化,您可以动态创建匿名类型,如下所示:

void Main()
{
    // import Newtonsoft.JsonConvert

    SecondClass secondClass = new SecondClass
    {
        Value = "Test"
    };

    MainClass mainClass = new MainClass
    {
        MyStringValue = "String Value",
        MyClassValue = secondClass
    };

    // The JSON as you expect
    var origJson = JsonConvert.SerializeObject(mainClass);
    Console.WriteLine(origJson);
    // The JSON Deserialized and the second class value outputted
    Console.WriteLine(JsonConvert.DeserializeObject<MainClass>(origJson).MyClassValue.Value);

    // The modified JSON as you wanted it
    var modJson = JsonConvert.SerializeObject(new { mainClass.MyStringValue, MyClassValue = mainClass.MyClassValue.Value });
    Console.WriteLine(modJson);

    // The modified JSON deserialized
    var deserialized = JsonConvert.DeserializeObject<ModMainClass>(modJson);
    Console.WriteLine(deserialized.MyStringValue);
}

public class ModMainClass
{
    public string MyStringValue { get; set; }
    public string MyClassValue { get; set; }
}

public class MainClass
{
   public string MyStringValue {get;set;}
   public SecondClass MyClassValue {get;set;}
}

public class SecondClass
{
    public string Value { get; set; }
} 
void Main()
{
//导入Newtonsoft.JsonConvert
SecondClass SecondClass=新的SecondClass
{
Value=“测试”
};
MainClass MainClass=新的MainClass
{
MyStringValue=“字符串值”,
MyClassValue=secondClass
};
//正如您所期望的那样,JSON
var origJson=JsonConvert.SerializeObject(mainClass);
控制台写入线(origJson);
//JSON被反序列化并输出第二个类值
WriteLine(JsonConvert.DeserializeObject(origJson.MyClassValue.Value));
//根据需要修改JSON
var modJson=JsonConvert.SerializeObject(新的{mainClass.MyStringValue,MyClassValue=mainClass.MyClassValue.Value});
Console.WriteLine(modJson);
//修改后的JSON被反序列化
var deserialized=JsonConvert.DeserializeObject(modJson);
WriteLine(反序列化的.MyStringValue);
}
公共类modmain类
{
公共字符串MyStringValue{get;set;}
公共字符串MyClassValue{get;set;}
}
公共类主类
{
公共字符串MyStringValue{get;set;}
公共第二类MyClassValue{get;set;}
}
公务舱二等舱
{
公共字符串值{get;set;}
} 

为此,您需要一个新类进行反序列化。但是,对于序列化,您可以动态创建匿名类型,如下所示:

void Main()
{
    // import Newtonsoft.JsonConvert

    SecondClass secondClass = new SecondClass
    {
        Value = "Test"
    };

    MainClass mainClass = new MainClass
    {
        MyStringValue = "String Value",
        MyClassValue = secondClass
    };

    // The JSON as you expect
    var origJson = JsonConvert.SerializeObject(mainClass);
    Console.WriteLine(origJson);
    // The JSON Deserialized and the second class value outputted
    Console.WriteLine(JsonConvert.DeserializeObject<MainClass>(origJson).MyClassValue.Value);

    // The modified JSON as you wanted it
    var modJson = JsonConvert.SerializeObject(new { mainClass.MyStringValue, MyClassValue = mainClass.MyClassValue.Value });
    Console.WriteLine(modJson);

    // The modified JSON deserialized
    var deserialized = JsonConvert.DeserializeObject<ModMainClass>(modJson);
    Console.WriteLine(deserialized.MyStringValue);
}

public class ModMainClass
{
    public string MyStringValue { get; set; }
    public string MyClassValue { get; set; }
}

public class MainClass
{
   public string MyStringValue {get;set;}
   public SecondClass MyClassValue {get;set;}
}

public class SecondClass
{
    public string Value { get; set; }
} 
void Main()
{
//导入Newtonsoft.JsonConvert
SecondClass SecondClass=新的SecondClass
{
Value=“测试”
};
MainClass MainClass=新的MainClass
{
MyStringValue=“字符串值”,
MyClassValue=secondClass
};
//正如您所期望的那样,JSON
var origJson=JsonConvert.SerializeObject(mainClass);
控制台写入线(origJson);
//JSON被反序列化并输出第二个类值
WriteLine(JsonConvert.DeserializeObject(origJson.MyClassValue.Value));
//根据需要修改JSON
var modJson=JsonConvert.SerializeObject(新的{mainClass.MyStringValue,MyClassValue=mainClass.MyClassValue.Value});
Console.WriteLine(modJson);
//修改后的JSON被反序列化
var deserialized=JsonConvert.DeserializeObject(modJson);
WriteLine(反序列化的.MyStringValue);
}
公共类modmain类
{
公共字符串MyStringValue{get;set;}
公共字符串MyClassValue{get;set;}
}
公共类主类
{
公共字符串MyStringValue{get;set;}
公共第二类MyClassValue{get;set;}
}
公务舱二等舱
{
公共字符串值{get;set;}
} 

你有两个选择一个是@Simonare提到的

或者将类的结构器
MainClass
更改为

public class MainClass<T>
{
    public string MyStringValue { get; set; }
    public T MyClassValue { get; set; }
}

public class SecondClass
{
    public string Value { get; set; }
}

var c=newmainclass();

你有两个选择一个是@Simonare提到的

或者将类的结构器
MainClass
更改为

public class MainClass<T>
{
    public string MyStringValue { get; set; }
    public T MyClassValue { get; set; }
}

public class SecondClass
{
    public string Value { get; set; }
}

var c=newmainclass();

实现这一点的一种方法是使用带有的。例如,可以为类创建自定义转换器:

public class SecondClassConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(SecondClass);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            if (reader.TokenType == JsonToken.String)
            {
                return new SecondClass
                {
                    Value = reader.Value.ToString()
                };
            }
        }
        catch (Exception ex)
        {
            throw new JsonSerializationException($"Error converting value {reader.Value} to type '{objectType}'.", ex);
        }

        throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing {nameof(SecondClass)}.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        var secondClass = (SecondClass)value;
        writer.WriteValue(secondClass.Value);
    }
}
然后将
jsonconverteratertribute
与该转换器一起使用:

public class MainClass
{
    public string MyStringValue { get; set; }
    [JsonConverter(typeof(SecondClassConverter))]
    public SecondClass MyClassValue { get; set; }
}

public class SecondClass
{
    public string Value { get; set; }
}
这将允许
MainClass
的所有序列化使用
SecondClassConverter
WriteJson
方法:

static void Main(string[] args)
{
    SecondClass secondClass = new SecondClass
    {
        Value = "Test"
    };

    MainClass mainClass = new MainClass
    {
        MyStringValue = "String Value",
        MyClassValue = secondClass
    };

    var json = JsonConvert.SerializeObject(mainClass);

    Console.WriteLine(json);
    Console.ReadLine();
}
static void Main(string[] args)
{
    var json = "{ \"MyStringValue\":\"String Value\", \"MyClassValue\": \"Test\" }";

    var decodedJson = JsonConvert.DeserializeObject<MainClass>(json);

    Console.WriteLine($"decodedJson.MyStringValue: {decodedJson.MyStringValue}");
    Console.WriteLine($"decodedJson.MyClassValue.Value: {decodedJson.MyClassValue.Value}");
    Console.ReadLine();
}
提供所需的JSON结果:


反序列化也可以工作,利用
SecondClassConverter
ReadJson
方法:

static void Main(string[] args)
{
    SecondClass secondClass = new SecondClass
    {
        Value = "Test"
    };

    MainClass mainClass = new MainClass
    {
        MyStringValue = "String Value",
        MyClassValue = secondClass
    };

    var json = JsonConvert.SerializeObject(mainClass);

    Console.WriteLine(json);
    Console.ReadLine();
}
static void Main(string[] args)
{
    var json = "{ \"MyStringValue\":\"String Value\", \"MyClassValue\": \"Test\" }";

    var decodedJson = JsonConvert.DeserializeObject<MainClass>(json);

    Console.WriteLine($"decodedJson.MyStringValue: {decodedJson.MyStringValue}");
    Console.WriteLine($"decodedJson.MyClassValue.Value: {decodedJson.MyClassValue.Value}");
    Console.ReadLine();
}
static void Main(字符串[]args)
{
var json=“{\'MyStringValue\':\'String Value\',\'MyClassValue\':\'Test\'”;
var decodedJson=JsonConvert.DeserializeObject(json);
Console.WriteLine($“decodedJson.MyStringValue:{decodedJson.MyStringValue}”);
WriteLine($“decodedJson.MyClassValue.Value:{decodedJson.MyClassValue.Value}”);
Console.ReadLine();
}
提供输出为:


实现这一点的一种方法是使用带有的。例如,可以为类创建自定义转换器:

public class SecondClassConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(SecondClass);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            if (reader.TokenType == JsonToken.String)
            {
                return new SecondClass
                {
                    Value = reader.Value.ToString()
                };
            }
        }
        catch (Exception ex)
        {
            throw new JsonSerializationException($"Error converting value {reader.Value} to type '{objectType}'.", ex);
        }

        throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing {nameof(SecondClass)}.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        var secondClass = (SecondClass)value;
        writer.WriteValue(secondClass.Value);
    }
}
然后将
jsonconverteratertribute
与该转换器一起使用:

public class MainClass
{
    public string MyStringValue { get; set; }
    [JsonConverter(typeof(SecondClassConverter))]
    public SecondClass MyClassValue { get; set; }
}

public class SecondClass
{
    public string Value { get; set; }
}
这将允许
MainClass
的所有序列化使用
SecondClassConverter
WriteJson
方法:

static void Main(string[] args)
{
    SecondClass secondClass = new SecondClass
    {
        Value = "Test"
    };

    MainClass mainClass = new MainClass
    {
        MyStringValue = "String Value",
        MyClassValue = secondClass
    };

    var json = JsonConvert.SerializeObject(mainClass);

    Console.WriteLine(json);
    Console.ReadLine();
}
static void Main(string[] args)
{
    var json = "{ \"MyStringValue\":\"String Value\", \"MyClassValue\": \"Test\" }";

    var decodedJson = JsonConvert.DeserializeObject<MainClass>(json);

    Console.WriteLine($"decodedJson.MyStringValue: {decodedJson.MyStringValue}");
    Console.WriteLine($"decodedJson.MyClassValue.Value: {decodedJson.MyClassValue.Value}");
    Console.ReadLine();
}
提供所需的JSON结果:


反序列化也可以工作,利用
SecondClassConverter
ReadJson
方法:

static void Main(string[] args)
{
    SecondClass secondClass = new SecondClass
    {
        Value = "Test"
    };

    MainClass mainClass = new MainClass
    {
        MyStringValue = "String Value",
        MyClassValue = secondClass
    };

    var json = JsonConvert.SerializeObject(mainClass);

    Console.WriteLine(json);
    Console.ReadLine();
}
static void Main(string[] args)
{
    var json = "{ \"MyStringValue\":\"String Value\", \"MyClassValue\": \"Test\" }";

    var decodedJson = JsonConvert.DeserializeObject<MainClass>(json);

    Console.WriteLine($"decodedJson.MyStringValue: {decodedJson.MyStringValue}");
    Console.WriteLine($"decodedJson.MyClassValue.Value: {decodedJson.MyClassValue.Value}");
    Console.ReadLine();
}
static void Main(字符串[]args)
{
var json=“{\'MyStringValue\':\'String Value\',\'MyClassValue\':\'Test\'”;
var decodedJson=JsonConvert.DeserializeObject(json);
Console.WriteLine($“decodedJson.MyStringValue:{decodedJson.MyStringValue}”);
WriteLine($“decodedJson.MyClassValue.Value:{decodedJson.MyClassValue.Value}”);
Console.ReadLine();
}
提供输出为:


谢谢,这正是我想要的。我在全局配置中添加了它:settings.Converters.A