.NET Framework 4.8 Remoting未强签名DLL版本冲突解决方案咨询
你尝试用类似Newtonsoft的绑定重定向配置无法解决问题,原因是程序集绑定重定向仅对强签名(强命名)的程序集生效,你的app_core.dll没有做强命名,配置中缺少必填的publicKeyToken属性,运行时不会识别并执行该重定向规则。同时.NET Remoting在处理远程调用的类型解析时,默认会严格校验类型所属程序集的完整标识(名称+版本+公钥Token),只要版本不一致就会判定为类型不匹配,导致通信失败。
以下是完全满足你要求的可行解决方案:
方案1:自定义Remoting序列化绑定器(仅需服务端修改,无侵入)
你只需要在授权服务端实现自定义的SerializationBinder,在类型解析时忽略app_core的版本号差异即可,代码示例如下:
public class IgnoreAppCoreVersionBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { // 拦截所有app_core相关的类型解析请求 if (assemblyName.StartsWith("app_core,")) { // 从当前已加载的app_core中查找对应类型,忽略版本差异 var targetAssembly = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == "app_core"); if (targetAssembly != null) { return targetAssembly.GetType(typeName, throwOnError: true); } } // 其他类型走默认解析逻辑 return Type.GetType($"{typeName}, {assemblyName}"); } }
然后在授权服务启动、注册Remoting信道的时候,将这个自定义绑定器注册到信道配置中:
var serverFormatterProvider = new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full, SerializerBinder = new IgnoreAppCoreVersionBinder() }; var channel = new TcpChannel( new Hashtable { ["port"] = 你的服务端口 }, null, serverFormatterProvider ); ChannelServices.RegisterChannel(channel, ensureSecurity: false);
该方案不需要修改任何客户端代码,不需要调整现有接口定义,也不需要对DLL做签名。
方案2:监听AppDomain程序集解析事件(实现更轻量)
如果你不想修改Remoting信道配置,可以直接在授权服务的启动入口处注册AssemblyResolve事件,强制所有版本的app_core都解析为服务端当前加载的版本:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var requestAssembly = new AssemblyName(args.Name); if (requestAssembly.Name == "app_core") { // 直接返回当前服务端已加载的app_core程序集,忽略请求的版本号 return AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == "app_core"); } return null; };
注意事项
上述方案的前提是你对app_core.dll的修改是向前兼容的,即旧版本接口的方法签名、参数结构没有发生破坏性变更,否则即使绕过了版本校验,调用也会出现运行时错误。如果后续需要对授权接口做破坏性修改,可以考虑给接口加版本号标识做单独兼容处理。
内容的提问来源于stack exchange,提问作者Robert Dehmel
相关产品推荐
相关产品推荐

