问题
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.
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});
}
}
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?
回答1:
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
}
}
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();
}
}
}
}
来源:https://stackoverflow.com/questions/21684184/why-does-json-net-fail-to-serialize-a-x509certificate2