替换system.windows.forms.webbrowser用Microsoft.web.webview2.winforms.webview2 in winforms应用程序

发布于 2025-01-28 18:01:17 字数 3298 浏览 5 评论 0原文

我正在使用Microsoft.web.webview2.winforms.webview2升级Winforms C#.NET 4.8 Framework应用程序并替换嵌入式浏览器System.Windows.Forms.webbrowser。我正在调用我的C#代码中一些浏览器托管的JavaScript函数,而且我的JavaScript函数确实调用了一些C#方法。 我已经使它工作了(信息源之一是文章 https://weblog.west.west-wind.com/posts/2021/jan /14/toth-the-new-chromium-webview2-control-a-a-spin-in-net-net-part-1#do-you-need-the-webview2 ),但是,我不是对我的代码中的序列化/避难所感到满意。令我困扰的是,交换是基于序列化的字符串。这种方法对我来说似乎有些原始。要调用JavaScript函数,我正在撰写一个源语句。另一方面,当我的浏览器脚本调用C#方法时,该参数是一个序列化的字符串(我知道是JSON格式化的),所有引用字符都逃脱了。

我的问题是:我是否应该以不同的方式意识到C#和JavaScript之间的相互作用?

这是我从winforms测试程序中使用JavaScript调用的两个C#代码片段,我为应对迁移而制作的:

public struct ConfigGraph3D
{
    public bool showServices { get; set; }
    public string viewStyle { get; set; }
    public bool enforceNodeLabels { get; set; }
    public bool enforceServiceLabels { get; set; }
    public bool planesVisible { get; set; }
    public bool embedded { get; set; }
}
// retrieving a JavaScript structure into a C# structure
//var CONFIG = { showServices: true, viewStyle: "O", enforceNodeLabels: false, 
//               enforceServiceLabels: false, planesVisible: true, embedded: false};
//
string invocation = "getConfig()";
string response = await browser.ExecuteScriptAsync(invocation);
// Notice here that I’m deserializing the data twice: first removing backslash escapes
// then converting it into the structure ConfigGraph3D.
string configStr = JsonSerializer.Deserialize<string>(response);
ConfigGraph3D config = JsonSerializer.Deserialize<ConfigGraph3D>(configStr);
textConfig.Text = response;
//
// sending a graph structure to JavaScript. 
// The properly formatted JSON structure is read from a file by yet it needs to be serialized 
// in order to add escape characters (backslash).
//
string invocation = getJsonFile (graphFilePath) ;
string response = await browser.ExecuteScriptAsync(invocation);
//
//
string getJsonFile (string graphFilePath)
{
    string contents = File.ReadAllText(graphFilePath);
    JsonSerializerOptions jso = new JsonSerializerOptions();
    jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
    string contents2 = JsonSerializer.Serialize(contents, jso);
    string invocation = "replaceModelList(" + contents2 + ")";
    return invocation;
}

从JavaScript中调用C#:


    public struct ItemSelectedInfo
    {
        public int id { get; set; }
        public string type { get; set; }
    }
    //
    // invoked from JavaScript 
    // var jsonObj = "{ \"id\": " + mesh._id2 + ", \"type\":\"" + mesh._type + "\"}";   
    // window.chrome.webview.hostObjects.sync.dotnet.SelectedinGraphic(jsonObj);
    //
    [ComVisible(true)]
    public class GraphInterface
    {
        public void SelectedinGraphic(string jsonInfo)
        {
            ItemSelectedInfo selectedNodeKey = JsonSerializer.Deserialize<ItemSelectedInfo>(jsonInfo);
            Debug.WriteLine("SelectedinGraphic: " + jsonInfo);
        }
    }


I am upgrading a WinForms C# .NET 4.8 Framework application and replacing the embedded browser System.Windows.Forms.WebBrowser with Microsoft.Web.WebView2.WinForms.WebView2. I’m invoking some browser-hosted JavaScript functions from my C# code, and also my JavaScript functions do invoke some C# methods.
I’ve made it working (one of the information sources was the article https://weblog.west-wind.com/posts/2021/Jan/14/Taking-the-new-Chromium-WebView2-Control-for-a-Spin-in-NET-Part-1#do-you-need-the-webview2), however, I’m not feeling comfortable with the serialization/deserialization in my code. What bothers me is that the exchange is based on serialized strings; that approach appears somewhat primitive to me. To invoke a JavaScript function, I’m composing a source statement. Other way around, when my browser script is invoking a C# method, the argument is a serialized string (for which I know is JSON formatted) with all quote characters escaped.

My question is: should I have realized the interaction between C# and JavaScript in a different way?

Here are two C# code fragments with JavaScript invocation from a WinForms test program I’ve produced to cope with the migration:

public struct ConfigGraph3D
{
    public bool showServices { get; set; }
    public string viewStyle { get; set; }
    public bool enforceNodeLabels { get; set; }
    public bool enforceServiceLabels { get; set; }
    public bool planesVisible { get; set; }
    public bool embedded { get; set; }
}
// retrieving a JavaScript structure into a C# structure
//var CONFIG = { showServices: true, viewStyle: "O", enforceNodeLabels: false, 
//               enforceServiceLabels: false, planesVisible: true, embedded: false};
//
string invocation = "getConfig()";
string response = await browser.ExecuteScriptAsync(invocation);
// Notice here that I’m deserializing the data twice: first removing backslash escapes
// then converting it into the structure ConfigGraph3D.
string configStr = JsonSerializer.Deserialize<string>(response);
ConfigGraph3D config = JsonSerializer.Deserialize<ConfigGraph3D>(configStr);
textConfig.Text = response;
//
// sending a graph structure to JavaScript. 
// The properly formatted JSON structure is read from a file by yet it needs to be serialized 
// in order to add escape characters (backslash).
//
string invocation = getJsonFile (graphFilePath) ;
string response = await browser.ExecuteScriptAsync(invocation);
//
//
string getJsonFile (string graphFilePath)
{
    string contents = File.ReadAllText(graphFilePath);
    JsonSerializerOptions jso = new JsonSerializerOptions();
    jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
    string contents2 = JsonSerializer.Serialize(contents, jso);
    string invocation = "replaceModelList(" + contents2 + ")";
    return invocation;
}

Invoking C# from JavaScript example:


    public struct ItemSelectedInfo
    {
        public int id { get; set; }
        public string type { get; set; }
    }
    //
    // invoked from JavaScript 
    // var jsonObj = "{ \"id\": " + mesh._id2 + ", \"type\":\"" + mesh._type + "\"}";   
    // window.chrome.webview.hostObjects.sync.dotnet.SelectedinGraphic(jsonObj);
    //
    [ComVisible(true)]
    public class GraphInterface
    {
        public void SelectedinGraphic(string jsonInfo)
        {
            ItemSelectedInfo selectedNodeKey = JsonSerializer.Deserialize<ItemSelectedInfo>(jsonInfo);
            Debug.WriteLine("SelectedinGraphic: " + jsonInfo);
        }
    }


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文