为什么Json.NET无法序列化X509Certificate2? [英] Why does Json.NET fail to serialize a X509Certificate2?

查看:93
本文介绍了为什么Json.NET无法序列化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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆