C# 如何在一个特定的序列化中序列化除特定属性以外的所有属性
我有一个类似这样的对象(显然是简化的) 我希望ETag是对象json序列化的散列,省略ETag属性(以防止递归循环)。但是,我不能只使用C# 如何在一个特定的序列化中序列化除特定属性以外的所有属性,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我有一个类似这样的对象(显然是简化的) 我希望ETag是对象json序列化的散列,省略ETag属性(以防止递归循环)。但是,我不能只使用[JsonIgnore]属性,因为在其他时候我希望能够用json序列化整个内容 所以我想要的是这样的东西 public string ETag { get { return Hash(JsonConvert.Serialize(this, p => p.Ignore(x=>x.ETag) )); }} 不幸的是,这不是一个存在的API。如何实
[JsonIgnore]
属性,因为在其他时候我希望能够用json序列化整个内容
所以我想要的是这样的东西
public string ETag { get {
return Hash(JsonConvert.Serialize(this, p => p.Ignore(x=>x.ETag) ));
}}
不幸的是,这不是一个存在的API。如何实现类似的功能?这并不漂亮,但在JSON序列化之后可以使用字符串替换。您可以将ETag设置为标记值,以便在序列化之后可以替换/删除该元素。您可以使用自定义的
IContractResolver
以编程方式忽略对象上的属性。因此,我认为我将采取的方法是创建一个简单的解析器,它可以专门忽略单个类型上的单个属性(显然,如果需要,您可以扩展它),然后创建一个可以使用该解析器序列化的帮助器方法。使用ETag
属性中的helper方法,您就可以开始了
以下是解析程序的代码:
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;
}
}
最后,这里是一个工作演示:
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="
}
Fiddle:不是最漂亮的解决方案,但我刚刚创建了一个类似的对象,可以从省略字段的主对象中构造,并在需要时序列化它。@BradleyDotNET是的,有很多方法可以使用automapper和其他东西来实现这一点,但维护起来很麻烦,因为我希望这个对象会更改lot。请给出代码?这样做仍然会调用Etag,导致递归循环。我知道有一种更好的方法来处理JsonSerializerSettings,我只是不知道如何避免使用字符串类型的属性名,可以使用表达式树解析来保持所有的强类型。我更新了布莱恩的例子:太好了。非常感谢!我不介意在本例中严格键入,因为在本例中,所有内容都是命名的属性实例的内部内容
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="
}