您可以使用自定义IContractResolver
以编程方式忽略对象的属性。所以我认为我会采取的方法是创建一个简单的解析器,可以明确地忽略单个类型的单个属性(显然,如果需要,可以扩展此属性),然后创建一个可以使用该解析器序列化的帮助器方法。使用ETag
属性中的帮助器方法,您很好。
下面是解析器代码:
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;
}
}
这里的辅助方法(我也是在那里扔,因为你没有在你的问题中定义它哈希helper方法):
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)));
}
}
}
最后,这里的工作演示:
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")); }
}
}
输出:
Etag = T99YVDlrbZ66YL2u5MYjyIyO4Qk=
{
"Name": "Joe",
"Age": 26,
"ETag": "T99YVDlrbZ66YL2u5MYjyIyO4Qk="
}
小提琴:https://dotnetfiddle.net/YgVJ4K
不是最漂亮的解决方案,但我刚刚创建了一个可以从省略领域的主要一个构造相似的对象,序列化,当我需要它。 – BradleyDotNET 2014-09-30 22:24:24
@BradleyDotNET是很多方式来做到这一点与automapper和东西,但它成为一个麻烦,因为我期望这个对象改变很多 – 2014-09-30 22:25:28