禁止序列化,允许对属性进行反序列化

时间:2014-03-17 20:56:47

标签: c# .net json serialization json.net

我有一个非常简单的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; }
}

属性IdCreatedDateLastModifiedDate是我不想被序列化的值(我正在与第三方API集成,而这些值永远不会更新)。

但是,当我使用JSON进行反序列化时,我希望用数据填充这些属性。

我尝试使用[JsonIgnore],但这导致在反序列化期间跳过属性。是否可以这种方式使用属性?

修改

我正在使用继承,因为我的所有对象都需要相同的基本属性。我总是 de / serialize到子类(例如Account):

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

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

2 个答案:

答案 0 :(得分:2)

从序列化中排除某些属性而不必修改类结构的一种方法是创建这样的自定义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将替换为您要排除的属性的名称:< / p>

[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;
    }
}

答案 1 :(得分:0)

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

序列化此类:

[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; }
}