You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用反射调用SubjectAlternativeNameBuilder的AddGeneralName方法时遭遇空引用异常,如何正确实现?

使用反射调用SubjectAlternativeNameBuilder的AddGeneralName方法时遭遇空引用异常,如何正确实现?

嘿,我来帮你捋捋问题出在哪,以及怎么搞定这个反射调用的问题。

首先,你遇到的NullReferenceException根源很明确:你调用typeof(SubjectAlternativeNameBuilder).GetMethod("AddGeneralName")的时候,没有指定绑定标志来获取非公开方法。AddGeneralName是SubjectAlternativeNameBuilder的内部非公开方法,默认的GetMethod只会查找公开方法,所以你拿到的methodInfo其实是null,最后调用Invoke的时候自然就空引用了。

另外,还有个隐藏的坑:你只给GeneralNameAsn设置了RegisteredId字段,但这个ASN.1类型是带类型标记的——它需要明确指定当前是哪种类型的通用名称(比如这里的RegisteredId),否则内部处理的时候也会出问题。

接下来给你修正后的完整代码,每一步我都标清楚为什么这么改:

var assembly = typeof(SubjectAlternativeNameBuilder).Assembly;
// 获取GeneralNameAsn类型
var generalNameAsnType = assembly.GetType("System.Security.Cryptography.Asn1.GeneralNameAsn");
// 获取对应的类型枚举(用来标记当前是RegisteredId类型)
var generalNameTypeEnum = assembly.GetType("System.Security.Cryptography.Asn1.GeneralNameType");

// 创建GeneralNameAsn实例
var generalNameAsn = Activator.CreateInstance(generalNameAsnType);

// 1. 先设置类型标记:必须指定这是RegisteredId类型
var typeField = generalNameAsnType.GetField("_type", BindingFlags.Instance | BindingFlags.NonPublic);
typeField.SetValue(generalNameAsn, Enum.Parse(generalNameTypeEnum, "RegisteredId"));

// 2. 设置RegisteredId的值(注意字段名是带下划线的内部字段,不是你原来写的RegisteredId)
var registeredIdField = generalNameAsnType.GetField("_registeredId", BindingFlags.Instance | BindingFlags.NonPublic);
registeredIdField.SetValue(generalNameAsn, "1.3.6.1.4.1.311.20.2.3");

// 3. 正确获取非公开的AddGeneralName方法:必须指定BindingFlags,同时明确参数类型
var addGeneralNameMethod = typeof(SubjectAlternativeNameBuilder)
    .GetMethod("AddGeneralName", 
               BindingFlags.Instance | BindingFlags.NonPublic, 
               new[] { generalNameAsnType });

// 4. 调用方法
var sanBuilder = new SubjectAlternativeNameBuilder();
addGeneralNameMethod.Invoke(sanBuilder, new[] { generalNameAsn });

// 之后就可以正常使用sanBuilder生成SAN了
var san = sanBuilder.Build();

我再给你划几个关键的注意点:

  • 调用GetMethod时一定要加BindingFlags.Instance | BindingFlags.NonPublic,否则拿不到内部方法;同时指定参数类型可以避免重载导致的匹配问题。
  • .NET的内部类型字段通常会用下划线开头(比如_type、_registeredId),不要直接用公开属性的名称去反射字段。如果不确定字段名,可以用generalNameAsnType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)打印所有字段来确认。
  • 必须给GeneralNameAsn设置类型标记,这个是ASN.1结构的要求,不设置的话即使调用成功,后续生成SAN也会失败。

如果之后还是遇到问题,可以先检查这几点:字段名是否匹配、绑定标志是否正确、类型标记有没有设置到位。

备注:内容来源于stack exchange,提问作者Yola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 18:13:15