JsonObjectAttribute 强制运行时的对象序列化



JsonObjectAttribute 可用于将实现 IEnumerable 的类序列化为 JSON 对象而不是 JSON 数组

一个完美的例子可以在这里找到。

它适用于我自己定义的类,因为我有控制权。但是当我尝试编写一个程序来处理第三方库时,我无法在这些类上添加 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);

这将生成您需要的输出。 如果需要,可以对其进行增强以检查类型或其任何基类型是否在哈希表中(如果需要(。

请注意,为了获得最佳性能,应缓存并重用协定解析程序。

相关内容

  • 没有找到相关文章

最新更新