启用.NET Native工具链时AddWebAllowedObject功能失效问题排查
我之前碰到过完全一样的问题,这是.NET Native编译优化带来的典型坑——它会自动移除那些被判定为「未被托管代码直接引用」的类型和方法,而你的回调方法只有JavaScript会调用,所以被误当成无用代码裁剪掉了。下面是亲测有效的修复方案:
核心原因
启用.NET Native工具链后,其链接器会做激进的代码裁剪优化。如果你的回调类/方法只在JavaScript中被调用,托管代码里没有显式的引用逻辑,.NET Native就会认为这些代码是冗余的,直接从编译后的程序集中移除,最终导致WebView找不到对应的回调方法。
具体修复步骤
1. 给回调类和方法添加[Preserve]特性
先引用System.Runtime.CompilerServices命名空间,然后给你的回调类和需要暴露给JS的方法加上[Preserve]特性,告诉编译器不要优化掉这些内容:
using System.Runtime.CompilerServices; [Preserve] public class HtmlCommunicator { [Preserve] public void onLocationSelect() { // 这里写你的UWP回调逻辑 } }
注意:JS中调用的方法名要和托管代码里的完全一致(大小写敏感),比如你JS里用的是onLocationSelect,托管方法名就不能写成OnLocationSelect。
2. 在Default.rd.xml中强制保留类型
如果[Preserve]特性还不够保险,可以在项目的Default.rd.xml配置文件中显式声明保留你的回调类,彻底杜绝被裁剪的可能:
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> <Application> <!-- 替换成你的回调类的完整命名空间+类名 --> <Type Name="YourProjectNamespace.HtmlCommunicator" Dynamic="Required All" /> </Application> </Directives>
Dynamic="Required All"会告诉.NET Native保留这个类的所有成员,包括JS要调用的方法。
3. 确认WebAllowedObject的注册时机
一定要在WebView的NavigationStarting事件中注册你的回调对象,这个时机能保证WebView加载页面时,对象已经被注入到JavaScript环境中:
private void MyWebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) { var communicator = new HtmlCommunicator(); // 第二个参数要和JS中引用的对象名一致(你代码里是sumorea_app) sender.AddWebAllowedObject("sumorea_app", communicator); }
额外调试小技巧
如果修复后还是没生效,可以用dnSpy打开编译后的程序集,检查你的回调类和方法是否还存在。如果已经被移除,说明优化规则没配置正确,再调整rd.xml或者[Preserve]特性的使用方式。
内容的提问来源于stack exchange,提问作者Palla Ravi

