Why does Json.NET fail to serialize a X509Certificate2?

こ雲淡風輕ζ 提交于 2020-05-15 04:57:48

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!