.NET NewtonSoft JSON десериализует карту для другого имени свойства

У меня есть строка JSON, которая получена от внешней стороны.

{ "team":[ { "v1":"", "attributes":{ "eighty_min_score":"", "home_or_away":"home", "score":"22", "team_id":"500" } }, { "v1":"", "attributes":{ "eighty_min_score":"", "home_or_away":"away", "score":"30", "team_id":"600" } } ] } 

Мои classы сопоставления:

 public class Attributes { public string eighty_min_score { get; set; } public string home_or_away { get; set; } public string score { get; set; } public string team_id { get; set; } } public class Team { public string v1 { get; set; } public Attributes attributes { get; set; } } public class RootObject { public List team { get; set; } } 

Вопрос в том, что мне не нравится «class атрибута» и «имя поля атрибутов» в classе Team. Вместо этого я хочу, чтобы его называли «TeamScore», а также удаляли «_» из имен полей и приводили имена.

 JsonConvert.DeserializeObject(jsonText); 

Я могу изменить class «Атрибут» на «TeamScore», но если я изменю имя подачи (атрибуты в classе команд), оно не будет десериализоваться правильно и даст мне значение null. Как я могу это преодолеть?

Json.NET имеет JsonPropertyAttribute который позволяет вам указать имя свойства JSON, поэтому ваш код должен быть:

 public class TeamScore { [JsonProperty("eighty_min_score")] public string EightyMinScore { get; set; } [JsonProperty("home_or_away")] public string HomeOrAway { get; set; } [JsonProperty("score ")] public string Score { get; set; } [JsonProperty("team_id")] public string TeamId { get; set; } } public class Team { public string v1 { get; set; } [JsonProperty("attributes")] public TeamScore TeamScores { get; set; } } public class RootObject { public List Team { get; set; } } 

Документация: Атрибуты сериализации

Если вы хотите использовать динамическое сопоставление и не хотите загромождать свою модель атрибутами, этот подход работал для меня

Применение:

 var settings = new JsonSerializerSettings(); settings.DateFormatString = "YYYY-MM-DD"; settings.ContractResolver = new CustomContractResolver(); this.DataContext = JsonConvert.DeserializeObject(jsonString, settings); 

Логика:

 public class CustomContractResolver : DefaultContractResolver { private Dictionary PropertyMappings { get; set; } public CustomContractResolver() { this.PropertyMappings = new Dictionary { {"Meta", "meta"}, {"LastUpdated", "last_updated"}, {"Disclaimer", "disclaimer"}, {"License", "license"}, {"CountResults", "results"}, {"Term", "term"}, {"Count", "count"}, }; } protected override string ResolvePropertyName(string propertyName) { string resolvedName = null; var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName); return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName); } } 

Добавление к решению Jacks. Мне нужно Deserialize, используя JsonProperty и Serialize, игнорируя JsonProperty (или наоборот). ReflectionHelper и Attribute Helper – это только вспомогательные classы, которые получают список свойств или атрибутов для свойства. Я могу включить, если кто-то действительно заботится. Используя приведенный ниже пример, вы можете сериализовать viewmodel и получить «Amount», даже если JsonProperty – «RecurringPrice».

  ///  /// Ignore the Json Property attribute. This is usefule when you want to serialize or deserialize differently and not /// let the JsonProperty control everything. ///  ///  public class IgnoreJsonPropertyResolver : DefaultContractResolver { private Dictionary PropertyMappings { get; set; } public IgnoreJsonPropertyResolver() { this.PropertyMappings = new Dictionary(); var properties = ReflectionHelper.GetGetProperties(false)(); foreach (var propertyInfo in properties) { var jsonProperty = AttributeHelper.GetAttribute(propertyInfo); if (jsonProperty != null) { PropertyMappings.Add(jsonProperty.PropertyName, propertyInfo.Name); } } } protected override string ResolvePropertyName(string propertyName) { string resolvedName = null; var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName); return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName); } } 

Применение:

  var settings = new JsonSerializerSettings(); settings.DateFormatString = "YYYY-MM-DD"; settings.ContractResolver = new IgnoreJsonPropertyResolver(); var model = new PlanViewModel() {Amount = 100}; var strModel = JsonConvert.SerializeObject(model,settings); 

Модель:

 public class PlanViewModel { ///  /// The customer is charged an amount over an interval for the subscription. ///  [JsonProperty(PropertyName = "RecurringPrice")] public double Amount { get; set; } ///  /// Indicates the number of intervals between each billing. If interval=2, the customer would be billed every two /// months or years depending on the value for interval_unit. ///  public int Interval { get; set; } = 1; ///  /// Number of free trial days that can be granted when a customer is subscribed to this plan. ///  public int TrialPeriod { get; set; } = 30; ///  /// This indicates a one-time fee charged upfront while creating a subscription for this plan. ///  [JsonProperty(PropertyName = "SetupFee")] public double SetupAmount { get; set; } = 0; ///  /// String representing the type id, usually a lookup value, for the record. ///  [JsonProperty(PropertyName = "TypeId")] public string Type { get; set; } ///  /// Billing Frequency ///  [JsonProperty(PropertyName = "BillingFrequency")] public string Period { get; set; } ///  /// String representing the type id, usually a lookup value, for the record. ///  [JsonProperty(PropertyName = "PlanUseType")] public string Purpose { get; set; } } 

Расширяя ответ Rentering.com , в сценариях, где нужно позаботиться о целом графике многих типов, и вы ищете строго типизированное решение, этот class может помочь, см. Использование (свободно) ниже. Он работает как черный список или белый список для каждого типа. Тип не может быть одновременно ( Gist – также содержит глобальный список игнорирования).

 public class PropertyFilterResolver : DefaultContractResolver { const string _Err = "A type can be either in the include list or the ignore list."; Dictionary> _IgnorePropertiesMap = new Dictionary>(); Dictionary> _IncludePropertiesMap = new Dictionary>(); public PropertyFilterResolver SetIgnoredProperties(params Expression>[] propertyAccessors) { if (propertyAccessors == null) return this; if (_IncludePropertiesMap.ContainsKey(typeof(T))) throw new ArgumentException(_Err); var properties = propertyAccessors.Select(GetPropertyName); _IgnorePropertiesMap[typeof(T)] = properties.ToArray(); return this; } public PropertyFilterResolver SetIncludedProperties(params Expression>[] propertyAccessors) { if (propertyAccessors == null) return this; if (_IgnorePropertiesMap.ContainsKey(typeof(T))) throw new ArgumentException(_Err); var properties = propertyAccessors.Select(GetPropertyName); _IncludePropertiesMap[typeof(T)] = properties.ToArray(); return this; } protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { var properties = base.CreateProperties(type, memberSerialization); var isIgnoreList = _IgnorePropertiesMap.TryGetValue(type, out IEnumerable map); if (!isIgnoreList && !_IncludePropertiesMap.TryGetValue(type, out map)) return properties; Func predicate = jp => map.Contains(jp.PropertyName) == !isIgnoreList; return properties.Where(predicate).ToArray(); } string GetPropertyName( Expression> propertyLambda) { if (!(propertyLambda.Body is MemberExpression member)) throw new ArgumentException($"Expression '{propertyLambda}' refers to a method, not a property."); if (!(member.Member is PropertyInfo propInfo)) throw new ArgumentException($"Expression '{propertyLambda}' refers to a field, not a property."); var type = typeof(TSource); if (!type.GetTypeInfo().IsAssignableFrom(propInfo.DeclaringType.GetTypeInfo())) throw new ArgumentException($"Expresion '{propertyLambda}' refers to a property that is not from type '{type}'."); return propInfo.Name; } } 

Применение:

 var resolver = new PropertyFilterResolver() .SetIncludedProperties( u => u.Id, u => u.UnitId) .SetIgnoredProperties( r => r.Responders) .SetIncludedProperties( b => b.Id) .Ignore(nameof(IChangeTracking.IsChanged)); //see gist 
  • Сериализация прерываний в .NET 4.5
  • Сериализация структур данных в C
  • Поле Gson Serialize, если оно не пустое или не пустое
  • Как заставить $ .serialize () учитывать отключенных: элементы ввода?
  • Как использовать Gson API Google для десериализации JSON правильно?
  • Сериализовать значение nullable int
  • ef4 причина Циркулярная ссылка в веб-службе
  • Java Serializable Object to Byte Array
  • Как писать и читать java-сериализованные объекты в файл
  • jQuery serialize не регистрирует флажки
  • Можете ли вы указать формат для XmlSerialization datetime?
  • Interesting Posts

    Как работает режим совместимости в Windows?

    Что означает операция c = a +++ b?

    андроидный fragment. Как сохранить состояния представлений в fragmentе, когда другой fragment нажат поверх него

    Вопрос для интервью – поиск в отсортированном массиве X для индекса i такой, что X = i

    Как я могу определить кодировку / кодовую страницу текстового файла

    получить контекст в classе без активности

    Почему я получаю «Полученное фатальное предупреждение: протокол_версии» или «не проверено подлинностью» от Maven Central?

    Не удается найти шаблон модели данных Entity Data ADO.net в VS2017

    PhoneGap: открытие внешних URL-адресов в Safari

    Невозможно использовать Intellij с созданной исходной папкой

    Могу ли я отключить олицетворение только в нескольких экземплярах

    Что такое Windows Enhanced Storage?

    Как я могу разбивать страницы WPF DataGrid?

    Включение / выключение состояния сеанса для каждого controllerа / метода действий

    Как вызвать метод Objective-C из метода C?

    Давайте будем гением компьютера.