You can use a custom IContractResolver to programmatically ignore object properties. Therefore, I think the approach I would like to take is to create a simple resolver that can specifically ignore one property for one type (obviously, you could extend it if necessary), and then create a helper method that can serialize using this resolver. Use the helper method from your ETag property, and you're good to go.
Here is the code for the recognizer:
class IgnorePropertyResolver : DefaultContractResolver { Type targetType; string targetPropertyName; public IgnorePropertyResolver(Type targetType, string propertyName) { this.targetType = targetType; this.targetPropertyName = propertyName; } protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { IList<JsonProperty> props = base.CreateProperties(type, memberSerialization); if (targetType == type) { props = props.Where(p => p.PropertyName != targetPropertyName).ToList(); } return props; } }
Here's a helper method (I also threw a Hash hash method there, since you did not define it in your question):
static class JsonHelper { public static string Serialize(object target, string propertyToIgnore) { JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new IgnorePropertyResolver(target.GetType(), propertyToIgnore); return JsonConvert.SerializeObject(target, settings); } public static string Hash(string json) { using (var sha = new SHA1Managed()) { return Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(json))); } } }
And finally, here's a working demo:
class Program { static void Main(string[] args) { Person p = new Person { Name = "Joe", Age = 26 }; Console.WriteLine("Etag = " + p.ETag); Console.WriteLine(); Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented)); } } public class Person { public string Name { get; set; } public int Age { get; set; } public string ETag { get { return JsonHelper.Hash(JsonHelper.Serialize(this, "ETag")); } } }
Output:
Etag = T99YVDlrbZ66YL2u5MYjyIyO4Qk= { "Name": "Joe", "Age": 26, "ETag": "T99YVDlrbZ66YL2u5MYjyIyO4Qk=" }
Fiddle: https://dotnetfiddle.net/YgVJ4K