禁止序列化,允许属性上的反序列化

本文关键字:属性 反序列化 序列化 许属性 禁止 | 更新日期: 2023-09-27 17:50:45

我有一个非常简单的c#类:

[Serializable]
[JsonObject]
public class ObjectBase {
    public string Id { get; set; }
    public string CreatedById { get; set; }
    public DateTime CreatedDate { get; set; }
    public string LastModifiedById { get; set; }
    public DateTime LastModifiedDate { get; set; }
}

属性Id, CreatedDateLastModifiedDate是我不想序列化的值(我正在与第三方API集成,并且这些值永远无法更新)。

但是,当我有JSON要反序列化时,我希望这些属性填充数据。

我尝试使用[JsonIgnore],但这会导致在反序列化期间跳过该属性。可以这样使用属性吗?

编辑:

我已经使用继承,因为我所有的对象都需要相同的基本属性。I 总是反/序列化到子类(例如Account):

[Serializable]
[JsonObject]
public class Account : ObjectBase {
    public string AccountNumber { get; set; }
    public string ParentId { get; set; }
}

例如,我可能有一个Account对象的实例,IdCreatedDate属性可能有一个值。当我将该对象序列化为JSON时,我不希望包含这些属性。但是,当我有JSON并进行反序列化时,我希望这些属性获得一个值。

禁止序列化,允许属性上的反序列化

在不修改类结构的情况下从序列化中排除某些属性的一种方法是创建一个自定义的ContractResolver,如下所示:

class CustomResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
        if (typeof(ObjectBase).IsAssignableFrom(type))
        {
            string[] excludeThese = new string[] { "Id", "CreatedDate", "LastModifiedDate" };
            props = props.Where(p => !excludeThese.Contains(p.PropertyName)).ToList();
        }
        return props;
    }
}

序列化时,只需将解析器添加到序列化器设置中:

Account account = new Account
{
    Id = "100",
    CreatedById = "2",
    CreatedDate = new DateTime(2014, 3, 12, 14, 52, 18, DateTimeKind.Utc),
    LastModifiedById = "3",
    LastModifiedDate = new DateTime(2014, 3, 17, 16, 3, 34, DateTimeKind.Utc),
    AccountNumber = "1234567",
    ParentId = "99"
};
JsonSerializerSettings settings = new JsonSerializerSettings()
{
    ContractResolver = new CustomResolver(),
    Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(account, settings);
Console.WriteLine(json);
输出:

{
  "AccountNumber": "1234567",
  "ParentId": "99",
  "CreatedById": "2",
  "LastModifiedById": "3"
}

另一种方法

如果你不喜欢解析器的方法,另一个选择是添加布尔ShouldSerializeX方法到你的类,其中X被替换为你想要排除的属性的名称:

[Serializable]
[JsonObject]
public class ObjectBase
{
    public string Id { get; set; }
    public string CreatedById { get; set; }
    public DateTime CreatedDate { get; set; }
    public string LastModifiedById { get; set; }
    public DateTime LastModifiedDate { get; set; }
    public bool ShouldSerializeId()
    {
        return false;
    }
    public bool ShouldSerializeCreatedDate()
    {
        return false;
    }
    public bool ShouldSerializeLastModifiedDate()
    {
        return false;
    }
}

对象继承是关键。您希望序列化属性/字段的一个子集,并反序列化整个集合。因此,使整个集合派生自子集,并在序列化和反序列化中适当地使用它们。

序列化这个类:

[Serializable]
[JsonObject]
public class ObjectBase
{
    public string CreatedById { get; set; }
    public string LastModifiedById { get; set; }
}

反序列化这个类:

[Serializable]
[JsonObject]
public class ObjectDeserializationBase : ObjectBase
{
    public string Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime LastModifiedDate { get; set; }
}