Большинство приведенных выше ответов очищаются от нотации Slice. Расширенный синтаксис индексирования, используемый для нарезки, является aList[start:stop:step]
базовыми примерами являются
Другие примеры нарезки: 15 Extended Slices
На самом деле существует несколько довольно простых подходов, которые вы можете использовать для достижения желаемого результата.
Предположим, например, что у вас в настоящее время определены ваши классы следующим образом:
class Config
{
public Fizz ObsoleteSetting { get; set; }
public Bang ReplacementSetting { get; set; }
}
enum Fizz { Alpha, Beta, Gamma }
class Bang
{
public string Value { get; set; }
}
И вы хотите это сделать:
string json = @"{ ""ObsoleteSetting"" : ""Gamma"" }";
// deserialize
Config config = JsonConvert.DeserializeObject<Config>(json);
// migrate
config.ReplacementSetting =
new Bang { Value = config.ObsoleteSetting.ToString() };
// serialize
json = JsonConvert.SerializeObject(config);
Console.WriteLine(json);
Чтобы получить это:
{"ReplacementSetting":{"Value":"Gamma"}}
Json. NET имеет возможность условно сериализовать свойства, ища соответствующие методы ShouldSerialize
в классе.
Чтобы использовать эту функцию, добавьте в ваш класс метод boolean ShouldSerializeBlah()
, где Blah
заменяется именем свойства, которое вы не хотите сериализовать. Сделать реализацию этого метода всегда возвращать false
.
class Config
{
public Fizz ObsoleteSetting { get; set; }
public Bang ReplacementSetting { get; set; }
public bool ShouldSerializeObsoleteSetting()
{
return false;
}
}
Примечание: если вам нравится этот подход, но вы не хотите испортить публичный интерфейс своего класса, введя ShouldSerialize
метод, вы можете использовать IContractResolver
, чтобы сделать то же самое программно. См. Сериализация условных свойств в документации.
Вместо использования JsonConvert.SerializeObject
для выполнения сериализации загрузите config в JObject
, а затем просто удалите нежелательное свойство из JSON перед его записью. Это всего лишь пара дополнительных строк кода.
JObject jo = JObject.FromObject(config);
// remove the "ObsoleteSetting" JProperty from its parent
jo["ObsoleteSetting"].Parent.Remove();
json = jo.ToString();
[JsonIgnore]
к свойству, которое вы не хотите сериализоваться. [JsonProperty]
к альтернативному сеттеру, присвоив ему то же имя JSON, что и исходное свойство. Вот пересмотренный класс Config
:
class Config
{
[JsonIgnore]
public Fizz ObsoleteSetting { get; set; }
[JsonProperty("ObsoleteSetting")]
private Fizz ObsoleteSettingAlternateSetter
{
// get is intentionally omitted here
set { ObsoleteSetting = value; }
}
public Bang ReplacementSetting { get; set; }
}
После того, как я потратил довольно много времени на поиск того, как помечать свойство класса De-Serializable и НЕ Serializable, я обнаружил, что вообще этого не существует; поэтому я придумал решение, которое объединяет две разные библиотеки или методы сериализации (System.Runtime.Serialization.Json & amp; Newtonsoft.Json), и это сработало для меня следующим образом:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Runtime.Serialization;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace LUM_Win.model
{
[DataContract]
public class User
{
public User() { }
public User(String JSONObject)
{
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(JSONObject));
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(User));
User user = (User)dataContractJsonSerializer.ReadObject(stream);
this.ID = user.ID;
this.Country = user.Country;
this.FirstName = user.FirstName;
this.LastName = user.LastName;
this.Nickname = user.Nickname;
this.PhoneNumber = user.PhoneNumber;
this.DisplayPicture = user.DisplayPicture;
this.IsRegistred = user.IsRegistred;
this.IsConfirmed = user.IsConfirmed;
this.VerificationCode = user.VerificationCode;
this.Meetings = user.Meetings;
}
[DataMember(Name = "_id")]
[JsonProperty(PropertyName = "_id")]
public String ID { get; set; }
[DataMember(Name = "country")]
[JsonProperty(PropertyName = "country")]
public String Country { get; set; }
[DataMember(Name = "firstname")]
[JsonProperty(PropertyName = "firstname")]
public String FirstName { get; set; }
[DataMember(Name = "lastname")]
[JsonProperty(PropertyName = "lastname")]
public String LastName { get; set; }
[DataMember(Name = "nickname")]
[JsonProperty(PropertyName = "nickname")]
public String Nickname { get; set; }
[DataMember(Name = "number")]
[JsonProperty(PropertyName = "number")]
public String PhoneNumber { get; set; }
[DataMember(Name = "thumbnail")]
[JsonProperty(PropertyName = "thumbnail")]
public String DisplayPicture { get; set; }
[DataMember(Name = "registered")]
[JsonProperty(PropertyName = "registered")]
public bool IsRegistred { get; set; }
[DataMember(Name = "confirmed")]
[JsonProperty(PropertyName = "confirmed")]
public bool IsConfirmed { get; set; }
[JsonIgnore]
[DataMember(Name = "verification_code")]
public String VerificationCode { get; set; }
[JsonIgnore]
[DataMember(Name = "meeting_ids")]
public List<Meeting> Meetings { get; set; }
public String toJSONString()
{
return JsonConvert.SerializeObject(this, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
}
}
}
Надеюсь, что это поможет ...
Чтобы ответить на ответ Тхо Хо, это также можно использовать для полей.
[JsonProperty(nameof(IgnoreOnSerializing))]
public string IgnoreOnSerializingSetter { set { IgnoreOnSerializing = value; } }
[JsonIgnore]
public string IgnoreOnSerializing;
В любой ситуации, когда допустимо, чтобы свойство десериализации было отмечено как внутреннее, есть замечательно простое решение, которое вообще не зависит от атрибутов. Просто пометьте свойство как внутренний get, но public set:
public class JsonTest {
public string SomeProperty { internal get; set; }
}
Это приведет к правильной десериализации с использованием настроек / resolvers / etc., Но свойство лишено из сериализованного вывода.
Мне нравится придерживаться атрибутов на этом, вот тот метод, который я использую, когда вам нужно десериализовать свойство, но не сериализуйте его или наоборот.
ШАГ 1 - Создайте пользовательский атрибут
public class JsonIgnoreSerializationAttribute : Attribute { }
ШАГ 2 - Создайте пользовательское соглашение об отказе
class JsonPropertiesResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
//Return properties that do NOT have the JsonIgnoreSerializationAttribute
return objectType.GetProperties()
.Where(pi => !Attribute.IsDefined(pi, typeof(JsonIgnoreSerializationAttribute)))
.ToList<MemberInfo>();
}
}
ШАГ 3 - добавьте атрибут, в котором сериализация не требуется, но десериализация -
[JsonIgnoreSerialization]
public string Prop1 { get; set; } //Will be skipped when serialized
[JsonIgnoreSerialization]
public string Prop2 { get; set; } //Also will be skipped when serialized
public string Prop3 { get; set; } //Will not be skipped when serialized
ШАГ 4 - Используйте его
var sweet = JsonConvert.SerializeObject(myObj, new JsonSerializerSettings { ContractResolver = new JsonPropertiesResolver() });
Надеюсь, это поможет! Также стоит отметить, что это также игнорирует свойства, когда происходит Deserialization, когда я занимаюсь сортировкой, я просто использую конвертер обычным способом.
JsonConvert.DeserializeObject<MyType>(myString);
со ссылкой на решение @ ThoHo, используя setter, на самом деле все, что необходимо, без дополнительных тегов.
Для меня у меня ранее был единственный идентификатор ссылки, который я хотел загрузить и добавить новая коллекция ссылочных идентификаторов. Изменив определение ссылочного идентификатора, будет только содержать метод setter, который добавит значение в новую коллекцию. Json не может записать значение обратно, если свойство не имеет get; method.
// Old property that I want to read from Json, but never write again. No getter.
public Guid RefId { set { RefIds.Add(value); } }
// New property that will be in use from now on. Both setter and getter.
public ICollection<Guid> RefIds { get; set; }
Этот класс теперь обратно совместим с предыдущей версией и сохраняет только RefIds для новых версий.