Reputation: 25551
I have a very simple C# class:
[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; }
}
The properties Id
, CreatedDate
and LastModifiedDate
are values that I don't want to be serialized (I'm integrating with a third party API, and those values can never be updated).
However, I would like those properties to be populated with data when I have JSON that I'm deserializing.
I tried using [JsonIgnore]
, but that results in the property being skipped during deserialization. Is it possible to use the properties in this manner?
Edit:
I am using inheritance already as all of my objects require the same base properties. I always de/serialize into the child class (e.g. Account
):
[Serializable]
[JsonObject]
public class Account : ObjectBase {
public string AccountNumber { get; set; }
public string ParentId { get; set; }
}
As an example, I might have an instance of the Account
object and the Id
and CreatedDate
properties could have a value. When I serialize that object into JSON, I don't want those properties to be included. However, when I have JSON and am deserializing, I want those properties to get a value.
Upvotes: 1
Views: 316
Reputation: 129827
One way to exclude certain properties from serialization without having to modify your class structure is to create a custom ContractResolver
like this:
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;
}
}
When you serialize, just add the resolver to the serializer settings:
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);
Output:
{
"AccountNumber": "1234567",
"ParentId": "99",
"CreatedById": "2",
"LastModifiedById": "3"
}
Another Approach
If you don't like the resolver approach, another alternative is to add boolean ShouldSerializeX
methods to your class where X
is replaced with names of the properties that you want to exclude:
[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;
}
}
Upvotes: 2
Reputation: 34922
Object inheritance is the key. You want to serialize a subset of properties/fields, and deserialize the full set. So, make the full set derive from the subset and use them appropriately in your serialization and deserialization.
Serialize this class:
[Serializable]
[JsonObject]
public class ObjectBase
{
public string CreatedById { get; set; }
public string LastModifiedById { get; set; }
}
Deserialize this class:
[Serializable]
[JsonObject]
public class ObjectDeserializationBase : ObjectBase
{
public string Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastModifiedDate { get; set; }
}
Upvotes: 0