WebView2与.NET互操作中Json反序列化ArgumentException问题排查
问题分析与解决思路
核心问题:双重序列化导致反序列化失败
你的问题确实是重复序列化引发的:
- JS端的
getFormData手动调用JSON.stringify(person)返回JSON字符串; - WebView2的
ExecuteScriptAsync执行JS后,会自动将JS返回值序列化为JSON格式字符串。最终拿到的dataJson是双重序列化后的转义字符串(比如原始{"FirstName":"ad"}会变成"\"{\\\"FirstName\\\":\\\"ad\\\"}\""); - 直接用
JsonConvert.DeserializeObject<CardHolder>(dataJson)时,实际是尝试把一个字符串(而非CardHolder的JSON结构)反序列化为对象,必然抛出序列化异常。
具体修复方案
方案1:移除JS端手动序列化(推荐)
修改JS的getFormData方法,直接返回JS对象,让ExecuteScriptAsync自动完成序列化:
function getFormData() { var firstName = document.getElementById('firstName').value; var lastName = document.getElementById('lastName').value; var email = document.getElementById('email').value; var cardNumber = document.getElementById('cardNumber').value; // 直接返回对象,无需JSON.stringify return { FirstName: firstName, LastName: lastName, Email: email, CardNumber: cardNumber }; }
此时.NET端拿到的dataJson是标准的CardHolder结构JSON字符串,直接反序列化即可正常工作。
方案2:保留JS端stringify时的.NET端二次处理
若无法修改JS代码,可在.NET端先将双重序列化的字符串还原为原始JSON,再反序列化为对象:
// 先解析出原始JSON字符串 string rawJson = JsonConvert.DeserializeObject<string>(dataJson); // 再反序列化为CardHolder var person = JsonConvert.DeserializeObject<CardHolder>(rawJson);
额外优化建议
- 异步代码优化:避免
ContinueWith嵌套异步操作,改用await简化逻辑并避免线程上下文问题:
await devToolsContext.ExposeFunctionAsync("submitData", async () => { string dataJson = await webView.CoreWebView2.ExecuteScriptAsync("window.getFormData()"); if (!string.IsNullOrEmpty(dataJson)) { await LogPersonDetails(dataJson); // 需将LogPersonDetails改为async Task返回类型 } else { throw new InvalidOperationException("Result of getFormData() is empty."); } });
同时将LogPersonDetails的返回类型从async void改为async Task,规避异步无返回值的潜在风险。
- innerHTML特殊字符转义:直接拼接字符串到innerHTML时,若内容含单引号、尖括号等会报错,建议通过JSON传递数据:
await webView.CoreWebView2.ExecuteScriptAsync($"document.getElementById('resultDisplay').innerHTML = JSON.parse({JsonConvert.SerializeObject(displayText)});");
内容的提问来源于stack exchange,提问作者Stephen
相关产品推荐
相关产品推荐

