我们有一些配置文件是通过使用Json.net序列化C#对象生成的.
我们希望将序列化类的一个属性从简单的枚举属性迁移到类属性.
一个简单的方法是将旧的enum属性保留在类上,并在我们加载配置时安排Json.net读取此属性,但是当我们下次序列化对象时不要再次保存它.我们将分别从旧枚举中处理生成新类.
是否有任何简单的方法来标记(例如,使用属性)C#对象的属性,以便Json.net仅在序列化时忽略它,但在反序列化时要注意它?
Bri*_*ers 109
实际上有几种相当简单的方法可用于实现您想要的结果.
例如,让我们假设您的类目前定义如下:
class Config
{
public Fizz ObsoleteSetting { get; set; }
public Bang ReplacementSetting { get; set; }
}
enum Fizz { Alpha, Beta, Gamma }
class Bang
{
public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
你想这样做:
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);
Run Code Online (Sandbox Code Playgroud)
要得到这个:
{"ReplacementSetting":{"Value":"Gamma"}}
Run Code Online (Sandbox Code Playgroud)
Json.NET能够通过ShouldSerialize在类中查找相应的方法来有条件地序列化属性.
要使用此功能,ShouldSerializeBlah()请在类中添加一个布尔方法,其中Blah替换为您不想序列化的属性的名称.使该方法的实现始终返回false.
class Config
{
public Fizz ObsoleteSetting { get; set; }
public Bang ReplacementSetting { get; set; }
public bool ShouldSerializeObsoleteSetting()
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
注意:如果您喜欢这种方法,但是您不想通过引入ShouldSerialize方法来混淆类的公共接口,则可以使用a IContractResolver以编程方式执行相同的操作.请参阅文档中的条件属性序列化.
而不是使用JsonConvert.SerializeObject进行序列化,将配置对象加载到a中JObject,然后在写出之前简单地从JSON中删除不需要的属性.这只是几行代码.
JObject jo = JObject.FromObject(config);
// remove the "ObsoleteSetting" JProperty from its parent
jo["ObsoleteSetting"].Parent.Remove();
json = jo.ToString();
Run Code Online (Sandbox Code Playgroud)
[JsonIgnore]属性应用于您不希望序列化的属性.[JsonProperty]属性应用于备用setter,为其提供与原始属性相同的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; }
}
Run Code Online (Sandbox Code Playgroud)
Iuc*_*unu 27
对于任何可以将仅反序列化属性标记为内部的情况,有一个非常简单的解决方案,完全不依赖于属性.只需将属性标记为内部get,但公共集:
public class JsonTest {
public string SomeProperty { internal get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这会导致使用默认设置/解析器/等正确反序列化,但该属性将从序列化输出中删除.
Jra*_*o11 26
我喜欢在这个上坚持使用属性,这是我在需要反序列化属性但不对其进行序列化时使用的方法,反之亦然.
第1步 - 创建自定义属性
public class JsonIgnoreSerializationAttribute : Attribute { }
Run Code Online (Sandbox Code Playgroud)
第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>();
}
}
Run Code Online (Sandbox Code Playgroud)
步骤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
Run Code Online (Sandbox Code Playgroud)
第4步 - 使用它
var sweet = JsonConvert.SerializeObject(myObj, new JsonSerializerSettings { ContractResolver = new JsonPropertiesResolver() });
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!另外值得注意的是,当反序列化发生时,这也将忽略属性,当我进行derserializing时,我只是以传统方式使用转换器.
JsonConvert.DeserializeObject<MyType>(myString);
Run Code Online (Sandbox Code Playgroud)
小智 7
使用setter属性:
[JsonProperty(nameof(IgnoreOnSerializing))]
public string IgnoreOnSerializingSetter { set { _ignoreOnSerializing = value; } }
[JsonIgnore]
private string _ignoreOnSerializing;
[JsonIgnore]
public string IgnoreOnSerializing
{
get { return this._ignoreOnSerializing; }
set { this._ignoreOnSerializing = value; }
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助.
小智 5
在我花了很长时间搜索如何将类属性标记为De-Serializable和NOT Serializable之后,我发现根本就没有这样做的事情; 所以我提出了一个结合了两种不同库或序列化技术的解决方案(System.Runtime.Serialization.Json和Newtonsoft.Json),它对我有用,如下所示:
然后使用"Newtonsoft.Json.JsonConvert.SerializeObject"进行序列化,并使用"System.Runtime.Serialization.Json.DataContractJsonSerializer"进行反序列化.
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 });
}
}
}
Run Code Online (Sandbox Code Playgroud)希望有帮助......