为什么Json.NET无法序列化X509Certificate2? [英] Why does Json.NET fail to serialize a X509Certificate2?
问题描述
每当我尝试使用Json.NET序列化X509Certificate2实例(不使用其ISerializable实现,但选择忽略它)时,Json.NET都会引发异常.
Whenever I try to serialize an X509Certificate2 instance with Json.NET (without using its ISerializable implementation, but electing to ignore it), Json.NET throws an exception.
异常消息是"System.Security.Cryptography.X509Certificates.X509Certificate2"上已经存在名称为"CertContext"的成员.使用JsonPropertyAttribute指定另一个名称."
The exception message is "A member with the name 'CertContext' already exists on 'System.Security.Cryptography.X509Certificates.X509Certificate2'. Use the JsonPropertyAttribute to specify another name."
我写了一个程序来复制它:
I wrote a program that reproduces it:
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
internal class Program
{
private static void Main(string[] args)
{
var resolver = new DefaultContractResolver
{
IgnoreSerializableInterface = true,
DefaultMembersSearchFlags =
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.GetProperty
};
JsonConvert.SerializeObject(new X509Certificate2(), new JsonSerializerSettings {ContractResolver = resolver});
}
}
调查之后,我注意到X509Certificate2实现了一个名为"CertContext"的属性,该属性在其基类X509Certificate中隐藏了一个具有相同名称的方法.我如何告诉Json.NET像往常一样只采用最派生的属性?
After investigating, I noticed that X509Certificate2 implements a property called "CertContext" which hides a method with the same name in its base class, X509Certificate. How can I tell Json.NET to just take the most derived property, like it usually does?
推荐答案
我最近遇到了需要序列化X509Certificate2
实例的需求,以便将差异比较到行为不同的两个假定相同的环境中.我可以通过以下JsonSerializerSettings
实现序列化:
I recently came across a need to serialize instances of X509Certificate2
in order to compare differences into two supposedly identical environments that were behaving differently. I was able to achieve serialization via the following JsonSerializerSettings
:
new JsonSerializerSettings {
Error = (s, a) => a.ErrorContext.Handled = true,
ContractResolver = new DefaultContractResolver {
IgnoreSerializableInterface = true
}
}
这是一个完整的工作示例,其中JSON序列化了本地计算机存储中的第一个证书并打开它:
Here's a complete working example which JSON serializes the first certificate in the local machine store and opens it:
namespace ConsoleApp1
{
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
class Program
{
static void Main(string[] args)
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
try
{
store.Open(OpenFlags.ReadOnly);
var cert = store.Certificates[0];
var path = Path.GetTempFileName();
File.WriteAllText(
path,
JsonConvert.SerializeObject(
cert, new JsonSerializerSettings {
Formatting = Formatting.Indented,
// Ignore serializtion errors
Error = (s, a) => a.ErrorContext.Handled = true,
ContractResolver = new DefaultContractResolver {
// Ensures all properties are serialized
IgnoreSerializableInterface = true
}
}
)
);
Process.Start(path);
}
finally
{
store.Close();
}
}
}
}
这篇关于为什么Json.NET无法序列化X509Certificate2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!