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

.NET Core Web API部署IIS后程序集名变更 反射获取控制器方法失败

问题背景
  • 运行环境:Visual Studio 2019,基于.NET Core开发Web API项目,采用Repository模式实现架构,需求为通过反射读取控制器内的所有方法与参数。
  • 原有仓储层反射实现代码:
var method = MethodBase.GetCurrentMethod();
_log4net.Info("Assembly Name : " + Assembly.GetCallingAssembly().FullName);
_log4net.Info("Method Name : " + method.Name);
_log4net.Info("Repository Name :" + method.ReflectedType.FullName);

var result =
((System.Reflection.TypeInfo)Assembly.GetCallingAssembly().GetTypes().Where(type
=> type.FullName.Contains("AsmeController")).FirstOrDefault()).DeclaredMethods;
_log4net.Info(result);
  • 异常现象:
    1. Debug调试模式下代码运行符合预期,可正常返回方法信息列表,日志显示对应业务程序集为Demo.dll
    2. Release模式发布部署到IIS后代码运行异常返回null;经日志排查,部署后通过Assembly.GetCallingAssembly()获取到的程序集名称从Demo.dll变为Anonymously Hosted DynamicMethods Assembly,无法匹配到AsmeController类型,最终反射获取DeclaredMethods失败。
可行解决建议

核心触发原因:Release模式下.NET Core JIT会做方法内联编译优化,同时代码中使用的LINQ Where查询会生成动态匿名方法,调用栈不再指向原始业务程序集,因此GetCallingAssembly()会拿到动态生成的匿名程序集,而非预期的Demo.dll

  • 优先采用直接绑定目标类型所属程序集的方案,稳定性最高,完全不受编译优化、动态方法生成影响。不要依赖调用栈判断程序集归属,示例代码如下:
// 直接通过已知控制器类型获取其所在的业务程序集,避免调用栈变动导致的定位错误
var businessAssembly = typeof(AsmeController).Assembly;
var targetController = businessAssembly.GetTypes()
    .FirstOrDefault(type => type.FullName != null && type.FullName.Contains("AsmeController"));

if (targetController != null)
{
    var result = targetController.GetTypeInfo().DeclaredMethods;
    _log4net.Info(result);
}
  • 如果不希望硬编码绑定具体控制器类型,可以遍历当前应用域加载的所有程序集,过滤掉动态程序集、系统框架程序集后再匹配目标控制器,示例代码如下:
var targetController = AppDomain.CurrentDomain.GetAssemblies()
    // 过滤动态生成的匿名程序集、.NET系统类库、微软官方框架类库
    .Where(asm => !asm.IsDynamic 
        && !asm.FullName.StartsWith("System.") 
        && !asm.FullName.StartsWith("Microsoft."))
    .SelectMany(asm => asm.GetTypes())
    .FirstOrDefault(type => type.FullName != null && type.FullName.Contains("AsmeController"));

if (targetController != null)
{
    var result = targetController.GetTypeInfo().DeclaredMethods;
    _log4net.Info(result);
}
  • 不推荐的临时方案:关闭项目编译优化。右键对应项目→选择「属性」→进入「生成」选项卡,取消勾选「优化代码」,发布部署时同样关闭优化配置。该方案会损失部分程序运行性能,仅适合临时调试使用。
  • 编码优化提示:原有代码未对FirstOrDefault()的匹配结果做空值判断,一旦类型匹配失败直接做类型强转就会触发空引用异常,反射逻辑必须增加空值校验,避免线上服务报错。

内容的提问来源于stack exchange,提问作者Surendra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:57:22