我遇到了外部资源不接受生成的 JSON 中的 $id 和 $ref 属性的问题。但是由于我们在内部需要它,我不能只在全局禁用 PreserveReferencesHandling。
我怎样才能只对一种类型禁用它?我已经看到了 [JsonObject]
属性,但是由于此类来自外部源,所以我无法将属性添加到它...
我查看了 IContractResolver,但无法弄清楚如何禁用那里的引用处理。
谢谢!
- JSON.Net v10.0.2
最佳答案
这可以通过 custom ContractResolver
来完成设置 JsonContract.IsReference == false
通过覆盖 DefaultContractResolver.CreateContract()
:
public class DisableReferencePreservationContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;
public DisableReferencePreservationContractResolver(IEnumerable<Type> types)
{
this.types = new HashSet<Type>(types);
}
bool ContainsType(Type type)
{
return types.Contains(type);
//return types.Any(t => t.IsAssignableFrom(type));
}
bool? GetIsReferenceOverride(Type type)
{
return ContainsType(type) ? false : (bool?)null;
}
protected override JsonContract CreateContract(Type objectType)
{
// Disable IsReference for this type of object
var contract = base.CreateContract(objectType);
contract.IsReference = contract.IsReference ?? GetIsReferenceOverride(objectType);
return contract;
}
}
应该向构造函数传递一个类型列表,其中的引用信息将被禁用。请注意,我排除了传递给契约(Contract)解析器的确切类型实例的此信息。如果您还想从派生类型的实例中排除此信息,您可以按如下方式修改 ContainsType()
:
bool ContainsType(Type type)
{
return types.Any(t => t.IsAssignableFrom(type));
}
另请注意,契约(Contract)解析器会禁用 PreserveReferencesHandling
当在 JsonSerializerSettings
中设置时,但当直接使用序列化属性(如 [JsonObject(IsReference = true)]
)设置时不是或 [JsonProperty(IsReference = true)]
在外部类型上。
样本 fiddle .
您可能想要 cache the contract resolver以获得最佳性能。
关于c# - 为单个外部类型禁用 JSON.Net PreserveReferencesHandling,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44515823/