Как сериализовать словарь как часть его родительского объекта с помощью Json.Net

Я использую Json.Net для сериализации. У меня есть class с словарем:

public class Test { public string X { get; set; } public Dictionary Y { get; set; } } 

Могу ли я каким-то образом сериализовать этот объект, чтобы получить следующий JSON

 { "X" : "value", "key1": "value1", "key2": "value2" } 

где «ключ1», «ключ2» являются ключами в словаре?

Если вы используете Json.Net 5.0.5 или новее, и вы готовы изменить тип словаря из Dictionary в Dictionary , тогда один простой способ выполнить то, что вы хотите, для добавления [JsonExtensionData] к вашему свойству словаря, например:

 public class Test { public string X { get; set; } [JsonExtensionData] public Dictionary Y { get; set; } } 

Затем ключи и значения помеченного словаря будут сериализованы как часть родительского объекта. Бонус заключается в том, что он также работает при десериализации: любые свойства в JSON, которые не соответствуют членам classа, будут помещены в словарь.

Внедрение classа JsonConverter: class CustomCreationConverter следует использовать в качестве базового classа для создания настраиваемого объекта .

Черновик версии конвертера (обработка ошибок может быть улучшена по вашему желанию):

 internal class TestObjectConverter : CustomCreationConverter { #region Overrides of CustomCreationConverter public override Test Create(Type objectType) { return new Test { Y = new Dictionary() }; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteStartObject(); // Write properties. var propertyInfos = value.GetType().GetProperties(); foreach (var propertyInfo in propertyInfos) { // Skip the Y property. if (propertyInfo.Name == "Y") continue; writer.WritePropertyName(propertyInfo.Name); var propertyValue = propertyInfo.GetValue(value); serializer.Serialize(writer, propertyValue); } // Write dictionary key-value pairs. var test = (Test)value; foreach (var kvp in test.Y) { writer.WritePropertyName(kvp.Key); serializer.Serialize(writer, kvp.Value); } writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jsonObject = JObject.Load(reader); var jsonProperties = jsonObject.Properties().ToList(); var outputObject = Create(objectType); // Property name => property info dictionary (for fast lookup). var propertyNames = objectType.GetProperties().ToDictionary(pi => pi.Name, pi => pi); foreach (var jsonProperty in jsonProperties) { // If such property exists - use it. PropertyInfo targetProperty; if (propertyNames.TryGetValue(jsonProperty.Name, out targetProperty)) { var propertyValue = jsonProperty.Value.ToObject(targetProperty.PropertyType); targetProperty.SetValue(outputObject, propertyValue, null); } else { // Otherwise - use the dictionary. outputObject.Y.Add(jsonProperty.Name, jsonProperty.Value.ToObject()); } } return outputObject; } public override bool CanWrite { get { return true; } } #endregion } 

Код клиента:

 var test = new Test { X = "123", Y = new Dictionary { { "key1", "value1" }, { "key2", "value2" }, { "key3", "value3" }, } }; string json = JsonConvert.SerializeObject(test, Formatting.Indented, new TestObjectConverter()); var deserializedObject = JsonConvert.DeserializeObject(json); 

Обратите внимание: существует потенциальное столкновение имен свойств и имен ключей словаря.

Вы можете создать этот конвертер, а затем присвоить его свойству. Принимал кусочки предлагаемых решений.

 public class DictionaryToJsonObjectConverter : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(IDictionary).IsAssignableFrom(objectType); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteRawValue(JsonConvert.SerializeObject(value, Formatting.Indented)); } } 

Затем используйте его в своем classе poco.

 public class Poco { [JsonProperty("myid")] public string Id{ get; set; } [JsonProperty("properties")] [JsonConverter(typeof(DictionaryToJsonObjectConverter))] public IDictionary Properties { get; set; } } 
  • Служба WCF Максимальная квота длины массива (16384) превышена
  • Информация о сериализации типов кеша Json.NET?
  • Специальная сериализация Jackson JSON для определенных полей
  • В чем разница между привязкой лямбды и метода на уровне выполнения?
  • Как сериализовать Java-примитивы с помощью Jersey REST
  • Автоматическая десериализация свойств C #
  • Существуют ли эквиваленты C ++ для функций протокола ввода-вывода протокола Buffer в Java?
  • jackson не десериализует общий список, который он сериализовал
  • Использование readObject / writeObject в сериализации
  • Jackson ObjectMapper - указать порядок сортировки свойств объекта
  • Можно ли выполнять бинарную сериализацию .NET в случае, если у вас нет исходного кода classа?
  • Давайте будем гением компьютера.