首页 > web前端 > js教程 > 正文

在WebView2中通过JSON序列化在C#与JavaScript之间传递数组

霞舞
发布: 2025-11-20 11:44:57
原创
795人浏览过

在WebView2中通过JSON序列化在C#与JavaScript之间传递数组

在webview2环境中,直接从c#javascript传递数组等复杂数据类型时,可能会遇到数据丢失或格式不匹配的问题。本教程将详细介绍一种健壮且通用的解决方案:利用json序列化。通过在c#端将数组转换为json字符串,然后在javascript端解析该字符串,可以确保复杂数据结构在两种语言之间准确无误地传递和重构,从而实现高效可靠的跨语言通信。

引言:C#与JavaScript数组传递的挑战

在开发基于WebView2的应用程序,特别是像VSTO Office Add-in这类需要C#后端逻辑与JavaScript前端交互的场景时,我们经常面临跨语言数据传递的需求。对于简单的字符串或基本数值类型,C#与JavaScript之间的直接传递通常表现良好。然而,当涉及到数组、对象等复杂数据类型时,直接的对象映射(如通过window.chrome.webview.hostObjects)可能无法按预期工作,导致JavaScript端接收到空数组或不完整的数据。

例如,一个C#的二维整数数组int[,] xx = { { 1, 2, 3 }, { 3, 4, 5 } };在尝试直接返回给JavaScript时,JavaScript控制台可能显示Array(0)或[],这表明数据并未正确地传递和解析。这种现象的根本原因在于,WebView2的宿主对象机制在处理复杂类型时,可能无法直接进行深层的数据结构转换,或者默认的转换规则不符合预期。

解决方案核心:JSON序列化与反序列化

为了解决C#与JavaScript之间复杂数据类型的传递问题,最通用、最健壮的方法是采用JSON(JavaScript Object Notation)作为中间数据格式。JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它被广泛应用于各种语言和平台之间的数据通信。

其核心思想是:

立即学习Java免费学习笔记(深入)”;

  1. C#端序列化: 在C#代码中,将需要传递的数组或对象序列化(转换)成一个JSON格式的字符串。
  2. 跨语言传递: 将这个JSON字符串作为普通字符串从C#传递给JavaScript。
  3. JavaScript端反序列化: 在JavaScript代码中,接收到JSON字符串后,将其反序列化(解析)回原生的JavaScript对象或数组。

这种方法确保了数据的完整性和结构的一致性,无论数据多么复杂,只要能表示为JSON,就能在两端之间可靠地传递。

C#端实现:将数组序列化为JSON字符串

在C#中,我们可以使用System.Text.Json命名空间下的JsonSerializer类(.NET Core 3.0+及.NET 5+内置)或流行的第三方库Newtonsoft.Json来完成JSON序列化。这里我们推荐使用System.Text.Json,因为它通常具有更好的性能和与.NET生态的紧密集成。

OmniAudio
OmniAudio

OmniAudio 是一款通过 AI 支持将网页、Word 文档、Gmail 内容、文本片段、视频音频文件都转换为音频播客,并生成可在常见 Podcast ap

OmniAudio 111
查看详情 OmniAudio

首先,确保你的项目引用了System.Text.Json(如果不是.NET Core/.NET 5+项目,可能需要通过NuGet安装)。

using System;
using System.Text.Json; // 引入System.Text.Json命名空间

public class HostObject
{
    public string GetArrayAsJson()
    {
        int[,] xx = { { 1, 2, 3 }, { 3, 4, 5 } };

        // 为了将多维数组正确序列化为JSON数组的数组,
        // 最好先将其转换为List<List<int>>或其他更易于序列化的结构。
        // 或者直接序列化,但JavaScript端可能需要特殊处理。
        // 对于本例,我们将其转换为List<int[]>以便JsonSerializer能更好地处理。
        // 更直接的方式是转换为List<List<int>>
        var list = new System.Collections.Generic.List<System.Collections.Generic.List<int>>();
        for (int i = 0; i < xx.GetLength(0); i++)
        {
            var row = new System.Collections.Generic.List<int>();
            for (int j = 0; j < xx.GetLength(1); j++)
            {
                row.Add(xx[i, j]);
            }
            list.Add(row);
        }

        // 使用JsonSerializer将List<List<int>>序列化为JSON字符串
        string jsonString = JsonSerializer.Serialize(list);
        Console.WriteLine($"C# serialized JSON: {jsonString}");
        return jsonString;
    }

    // 示例:传递一个字符串数组
    public string GetStringArrayAsJson()
    {
        string[] names = { "Alice", "Bob", "Charlie" };
        string jsonString = JsonSerializer.Serialize(names);
        Console.WriteLine($"C# serialized string array JSON: {jsonString}");
        return jsonString;
    }

    // 示例:传递一个匿名对象数组
    public string GetObjectArrayAsJson()
    {
        var users = new[]
        {
            new { Id = 1, Name = "Alice" },
            new { Id = 2, Name = "Bob" }
        };
        string jsonString = JsonSerializer.Serialize(users);
        Console.WriteLine($"C# serialized object array JSON: {jsonString}");
        return jsonString;
    }
}
登录后复制

在上述代码中,GetArrayAsJson方法将一个二维整数数组转换为List<List<int>>,然后使用JsonSerializer.Serialize方法将其序列化为一个JSON字符串。GetStringArrayAsJson和GetObjectArrayAsJson展示了如何处理一维字符串数组和匿名对象数组。

JavaScript端实现:接收并解析JSON字符串

在JavaScript端,我们通过window.chrome.webview.hostObjects调用C#方法后,会接收到一个JSON字符串。我们需要使用JavaScript内置的JSON.parse()方法将这个字符串解析回原生的JavaScript数组或对象。

// 假设C#的HostObject实例被命名为'control'并暴露给JavaScript
class WebView2HostInterface {
    async getArrayFromCSharp() {
        return new Promise(async (resolve, reject) => {
            try {
                // 调用C#方法,该方法返回一个JSON字符串
                let jsonString = await window.chrome.webview.hostObjects.control.GetArrayAsJson();
                console.log("Received JSON string from C#:", jsonString);

                // 使用JSON.parse()将JSON字符串解析为JavaScript数组
                let resultArray = JSON.parse(jsonString);
                console.log("Parsed JavaScript array:", resultArray);
                console.log("Type of parsed result:", typeof resultArray);
                console.log("Is it an array?", Array.isArray(resultArray));
                resolve(resultArray);
            } catch (error) {
                console.error("Error getting array from C#:", error);
                reject(error);
            }
        });
    }

    async getStringArrayFromCSharp() {
        return new Promise(async (resolve, reject) => {
            try {
                let jsonString = await window.chrome.webview.hostObjects.control.GetStringArrayAsJson();
                let resultArray = JSON.parse(jsonString);
                console.log("Parsed JavaScript string array:", resultArray);
                resolve(resultArray);
            } catch (error) {
                console.error("Error getting string array from C#:", error);
                reject(error);
            }
        });
    }

    async getObjectArrayFromCSharp() {
        return new Promise(async (resolve, reject) => {
            try {
                let jsonString = await window.chrome.webview.hostObjects.control.GetObjectArrayAsJson();
                let resultArray = JSON.parse(jsonString);
                console.log("Parsed JavaScript object array:", resultArray);
                resolve(resultArray);
            } catch (error) {
                console.error("Error getting object array from C#:", error);
                reject(error);
            }
        });
    }
}

// 示例调用
const hostInterface = new WebView2HostInterface();
hostInterface.getArrayFromCSharp().then(data => {
    console.log("Successfully received and parsed array:", data);
}).catch(err => {
    console.error("Failed to get array:", err);
});

hostInterface.getStringArrayFromCSharp().then(data => {
    console.log("Successfully received and parsed string array:", data);
});

hostInterface.getObjectArrayFromCSharp().then(data => {
    console.log("Successfully received and parsed object array:", data);
});
登录后复制

通过上述JavaScript代码,JSON.parse(jsonString)将把C#传递过来的JSON字符串转换为一个真正的JavaScript数组,你可以像操作任何JavaScript数组一样操作它。

优势与最佳实践

  1. 数据完整性与类型匹配: JSON作为一种通用格式,能够准确地表示各种复杂的数据结构,包括嵌套数组和对象,确保数据在C#和JavaScript之间传递时保持其完整性和原始结构。
  2. 语言无关性: JSON是一种标准格式,不依赖于任何特定的编程语言,因此它不仅适用于C#和JavaScript,也适用于与其他语言的交互。
  3. 可读性强: JSON格式直观易懂,便于调试和排查问题。
  4. 错误处理: 在C#端序列化和JavaScript端反序列化时,都应包含错误处理机制(如try-catch块),以应对数据格式不正确或网络传输中断等异常情况。
  5. 性能考虑: 对于非常大的数据集,序列化和反序列化可能会带来一定的性能开销。在这些情况下,可以考虑对数据进行分页或增量加载,或者评估其他二进制序列化方案(如果性能是关键瓶颈)。然而,对于大多数WebView2应用场景,JSON的性能开销通常可以忽略不计。
  6. 数据类型映射: 了解JSON如何映射C#和JavaScript的数据类型至关重要。例如,C#的int、double会映射为JSON数字,string映射为JSON字符串,bool映射为JSON布尔值,List<T>或T[]映射为JSON数组,自定义类或匿名对象映射为JSON对象。

总结

在WebView2环境中,为了实现C#与JavaScript之间复杂数据类型(尤其是数组和对象)的可靠传递,采用JSON序列化和反序列化是一种标准且高效的解决方案。通过在C#端将数据结构转换为JSON字符串,并在JavaScript端将其解析回来,开发者可以确保数据的完整性和一致性,从而构建出更加健壮和功能丰富的跨平台应用。这种方法不仅解决了数据类型不匹配的问题,还为C#和JavaScript之间的灵活数据交换提供了一个通用的、易于维护的框架。

以上就是在WebView2中通过JSON序列化在C#与JavaScript之间传递数组的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号