javascript - WebView2:通过 Javascript 代码在 C# 中设置对象属性

标签 javascript c# .net wpf webview2

这是 this question 的后续内容.

我正在将 WPF 应用程序从 CEFSharp 移植到 WebView2。我有一个 HostObject,需要从 WebView2 窗口中的 js 访问。就是这样,精简了。

using System;
using System.Runtime.InteropServices;

namespace webview2Demo
{
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class Api
    {
        public string Username { get; set; }
        public string Version = "1.1.1";
        public Api()  //ctor
        {
        }
    }
}

我可以在 WebView2 控件的 NavigationStarting 事件中成功使用此行,使对象在 Javascript 中可见。到目前为止一切顺利。

webView.CoreWebView2.AddHostObjectToScript("api", new API());

我可以像这样检索公共(public)属性和成员。到目前为止一切顺利。

(async function foo () {
  const api = chrome.webview.hostObjects.api
  const ver = await api.Version
  alert (ver)
})();

我的问题:我可以在没有任何异步竞争条件或死锁风险的情况下可靠地设置这样的属性吗? api.Username = 'whoever' 它似乎有效,但我还没有找到它的记录。

(async function foo () {
  const api = chrome.webview.hostObjects.api
  api.Username = 'whoever'
  const user = await api.Username
  alert (user)
})();

文档说 HostObject 是通过 Promises 公开的。 我是否正确击球二传手?

最佳答案

当您在 JavaScript 代理上为通过 CoreWebView2.AddHostObjectToScript 创建的主机对象设置属性时,与获取属性或调用方法不同,分配返回与分配的值相同的值,而不是表示分配完成的 promise 。属性分配确实会生成一条消息发送回 WebView2 主机应用程序进程,并且属性将被分配,只是您不会 promise 在完成时告诉您。

设置主机属性

或者,您可以使用setHostProperty ,一个将执行属性分配并返回一个 promise 的方法,该 promise 将在属性分配完成时解析。

(async function foo () {
  const api = chrome.webview.hostObjects.api
  await api.setHostProperty('Username', 'whoever');
  const user = await api.Username
  alert (user)
})();

同步代理

还有代理的同步版本。只要异步代理返回 Promise,同步代理就会阻塞 JavaScript 线程,等待 WebView2 主机进程的响应。通常,您不想阻止 JavaScript 线程等待跨进程调用,但在某些情况下,这可能更实用或更可接受。异步代理有一个 sync 方法,它将返回代理的同步版本(异步)。

(async function foo () {
  // Note the one await call to get from async proxies to sync proxies
  const syncHostObjects = await chrome.webview.hostObjects.sync;
  const api = syncHostObjects.api;
  api.Username = 'whoever';
  const user = api.Username
  alert (user)
})();

依赖队列

由于所有 JavaScript 代理消息都在同一队列上传输,并且必须在 WebView2 主机应用程序进程中的同一线程上处理,因此使用属性 setter 而不是等待其完成然后调用 getter 可能会仍然强制获取消息等待设置完成并且您的原始代码没有问题。

关于javascript - WebView2:通过 Javascript 代码在 C# 中设置对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68623267/

相关文章:

.net - 在一个租户中创建多个企业应用程序注册到同一 Web 应用程序

android - Visual Studio 2022 17.4.3 .NET MAUI Android 模拟不起作用

javascript - 如何提高webpack的执行速度?

javascript - Internet Explorer 和 Firefox 将内联 CSS 转换为奇怪的东西

javascript - 检测无法显示 HTML5 的浏览器

c# - 如何将 DBNull 值传递给参数化的 SELECT 语句?

c# - C# 中 Exception.Data 可以为 null 吗?

javascript - 使用 css 和 javascript 显示文件名

c# - 查询 parent.attribute 等于 LINQ to XML 中的某个值

.net - 从youtube链接获取youtube嵌入视频代码?