C#通过Invoke向JavaScript传参报DISP_E_UNKNOWNNAME错误如何解决
WPF WebBrowser调用JS抛出DISP_E_UNKNOWNNAME异常解决方案
异常触发原因
- 调用时序错误:
WebBrowser.Navigate方法为异步执行,调用后不会等待页面解析完成就直接运行后续代码。在导航后立刻调用InvokeScript时,页面DOM、JS全局上下文还未完成初始化,全局作用域下找不到SetCoords函数,直接触发0x80020006 (DISP_E_UNKNOWNNAME)未知名称COM异常。 - JS语法兼容问题:定义的
SetCoords函数使用long作为形参名,long是ECMAScript保留字,在WPF WebBrowser默认依赖的IE内核环境下,可能导致函数解析失败,无法挂载到全局上下文。
InvokeScript传参修复方案
1. C#端调整调用时序
不要在Navigate调用后直接执行脚本,监听WebBrowser的LoadCompleted事件,等页面完全加载完成后再调用JS函数:
// 窗口初始化时注册加载完成事件,避免重复注册 public MainWindow() { InitializeComponent(); wb.LoadCompleted += Wb_LoadCompleted; } private double coord1 = 39.9; private double coord2 = 116.4; private void WebBrowser_Clicked(object sender, RoutedEventArgs e) { wb.Navigate("C:/Users/intern3/source/repos/MarketingProject/Samples/WPF/RESTToolkitTestApp/index.htm"); } private void Wb_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) { // 页面加载完成后再执行JS调用,参数传入基础数值类型即可 wb.InvokeScript("SetCoords", new object[] { coord1, coord2 }); }
2. JS端修复语法问题
修复保留字作为形参的问题,调整参数名:
var map; var lattitude = 34.2; var longitude = -117.8; // 替换保留字long为lng,避免IE内核下解析失败 function SetCoords(lat, lng) { lattitude = lat; longitude = lng; // 若地图已初始化,可在此处直接更新地图视角 if(map) { map.setView({ center: new Microsoft.Maps.Location(lat, lng) }) } }
本地HTML通过URL查询字符串传参方案
本地HTML文件支持查询字符串传参,不需要调用InvokeScript,实现更简便,注意需要使用标准file:///协议格式拼接路径:
C#端代码
private void WebBrowser_Clicked(object sender, RoutedEventArgs e) { // 拼接坐标到查询参数,转义为file协议地址 string targetUrl = $"file:///C:/Users/intern3/source/repos/MarketingProject/Samples/WPF/RESTToolkitTestApp/index.htm?lat={coord1}&lng={coord2}"; wb.Navigate(targetUrl); }
JS端参数解析代码
var map; var lattitude = 34.2; var longitude = -117.8; // 页面加载时自动解析URL参数 window.onload = function() { const searchParams = new URLSearchParams(window.location.search); lattitude = parseFloat(searchParams.get('lat')) || 34.2; longitude = parseFloat(searchParams.get('lng')) || -117.8; // 后续直接使用坐标初始化地图即可 }
额外注意事项
- WPF自带WebBrowser默认使用IE7内核渲染,若要让页面
IE=edge的兼容标签生效,需要在程序运行时写入对应注册表配置,指定当前程序使用高版本IE内核渲染页面。 InvokeScript仅支持传递基础类型(数字、字符串、布尔值)参数,不要传入复杂C#对象,否则会出现序列化错误。
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

