You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.NET 8 MAUI(MacOS端调试运行)从WebView本地存储获取数据时返回无效值(\0\0…)的问题求助

.NET 8 MAUI(MacOS端调试运行)从WebView本地存储获取数据时返回无效值(\0\0…)的问题求助

我之前在MAUI MacOS项目里也碰到过几乎一模一样的问题!你遇到的其实是.NET和Objective-C桥接层对NSString类型处理的坑,直接调用NSObject.ToString()并不会正确获取到字符串内容,反而会返回底层的无效值(就是你看到的\0\0…)。

问题根源

当你通过WKWebView.EvaluateJavaScriptAsync获取localStorage的值时,返回的NSObject如果是字符串类型,它本质上是Objective-C的NSString对象。但.NET中NSObject的默认ToString()方法并不会解析NSString的实际内容,而是返回对象的内部描述信息(比如内存相关的垃圾值)。调试器能看到正确值,是因为它直接读取了Objective-C对象的原始内容,没有经过.NET桥接层的转换。

另外,你提到通用的webview.EvaluateJavaScriptAsync返回null,这大概率是MAUI MacOS端WebView的抽象层实现限制导致的,直接操作底层WKWebView的方式是对的,不用换回去。

解决方案

你需要把返回的NSObject强转为Foundation.NSString,再调用ToString()才能拿到正确的字符串内容。具体修正代码如下:

完整修正后的代码

首先确保你引用了必要的命名空间:

using Foundation;
using WebKit;

然后修改按钮点击事件的代码:

private async void btnLoggedIn_Clicked(object sender, EventArgs e)
{
    try
    {
        // 先确保WebView的PlatformView已经初始化完成
        var wkWebView = webview.Handler.PlatformView as WKWebView;
        if (wkWebView == null)
        {
            // 处理WebView未初始化的情况,比如提示用户或重试
            return;
        }

        // 执行JS获取localStorage中的dps值
        var macosResults = await wkWebView.EvaluateJavaScriptAsync("localStorage.getItem('dps');");

        // 关键:将NSObject强转为NSString再转换为.NET字符串
        if (macosResults is NSString dpsString)
        {
            var stringResults = dpsString.ToString();
            // 现在stringResults就是你需要的JSON字符串了
            // 可以在这里添加反序列化逻辑,比如:
            // var dpsData = JsonSerializer.Deserialize<YourDpsModel>(stringResults);
        }
        else if (macosResults == null)
        {
            // 处理localStorage中没有dps键的情况
        }
    }
    catch (Exception ex)
    {
        // 建议在这里添加日志或错误提示,方便排查问题
        Console.WriteLine($"获取localStorage数据失败:{ex.Message}");
    }
}

额外提示

  1. 确保WebView已完全加载:如果在页面还没加载完成时调用EvaluateJavaScriptAsync,可能会拿到null或无效值,你可以监听WebView.Navigated事件,在页面加载完成后再允许用户点击按钮。
  2. 提前验证localStorage存在性:可以先执行一段JS确认localStorage和目标键存在,避免无效调用:
    var existsCheck = await wkWebView.EvaluateJavaScriptAsync("typeof localStorage !== 'undefined' && localStorage.getItem('dps') !== null;");
    if (existsCheck is NSNumber existsFlag && existsFlag.BoolValue)
    {
        // 再执行获取数据的逻辑
    }
    

内容来源于stack exchange

火山引擎 最新活动