JsonObjectAttribute 可用于将实现 IEnumerable
一个完美的例子可以在这里找到。
它适用于我自己定义的类,因为我有控制权。但是当我尝试编写一个程序来处理第三方库时,我无法在这些类上添加 JsonObjectAttribute。
有没有另一种方法可以告诉JsonConvert.SerializeObject像JsonObjectAttribute那样做类似的事情?
更新:
这是我从文档中复制和粘贴的示例 Json.net。
[JsonObject]
public class Directory : IEnumerable<string>
{
public string Name { get; set; }
public IList<string> Files { get; set; }
public Directory()
{
Files = new List<string>();
}
public IEnumerator<string> GetEnumerator()
{
return Files.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Directory directory = new Directory
{
Name = "My Documents",
Files =
{
"ImportantLegalDocuments.docx",
"WiseFinancalAdvice.xlsx"
}
};
string json = JsonConvert.SerializeObject(directory, Formatting.Indented);
Console.WriteLine(json);
// {
// "Name": "My Documents",
// "Files": [
// "ImportantLegalDocuments.docx",
// "WiseFinancalAdvice.xlsx"
// ]
// }
现在,只要想想 [JsonObject] 不在那个类定义上,那么你怎么能达到相同的结果呢?
您可以创建一个自定义协定解析程序,该解析程序维护应序列化为对象的类型列表:
public class ObjectOverrideContractResolver : DefaultContractResolver
{
readonly HashSet<Type> overrideObjectTypes;
public ObjectOverrideContractResolver(IEnumerable<Type> overrideObjectTypes)
{
if (overrideObjectTypes == null)
throw new ArgumentNullException();
this.overrideObjectTypes = new HashSet<Type>(overrideObjectTypes);
}
protected override JsonContract CreateContract(Type objectType)
{
if (overrideObjectTypes.Contains(objectType))
{
var contract = CreateObjectContract(objectType);
// Mark get-only properties like Count as ignored
foreach (var property in contract.Properties)
{
if (!property.Writable)
property.Ignored = true;
}
return contract;
}
else
{
var contract = base.CreateContract(objectType);
return contract;
}
}
}
然后在JsonSerializerSettings.ContractResolver
中设置它:
var resolver = new ObjectOverrideContractResolver(new[] { typeof(Directory) });
var settings = new JsonSerializerSettings { ContractResolver = resolver };
var json = JsonConvert.SerializeObject(directory, Formatting.Indented, settings);
这将生成您需要的输出。 如果需要,可以对其进行增强以检查类型或其任何基类型是否在哈希表中(如果需要(。
请注意,为了获得最佳性能,应缓存并重用协定解析程序。