MAUI怎么从JavaScript调用C#代码 WebView与MAUI通信

来源:这里教程网 时间:2026-02-21 17:36:45 作者:

MAUI 中通过 WebView 实现 JavaScript 调用 C# 代码,核心是使用 WebView.EvaluateJavaScriptAsync 配合 WebView.RegisterScriptableObject(仅限 Android/iOS)或更通用的 WebView.PostWebMessageAsync / WebMessageReceived(推荐跨平台方案)。但注意:MAUI 的 WebView 默认不支持直接注册 JS 对象(如 UWP/WinUI 风格),需按平台适配,主流且稳定的方式是基于 WebMessage 的双向通信。

使用 WebMessage 实现 JS → C#(推荐跨平台)

这是 MAUI 官方推荐、全平台(Android、iOS、Windows、macOS)都支持的方式,无需平台特定代码,依赖

WebView.WebMessageReceived
事件和 JS 端的
window.chrome.webview.postMessage
(Windows)或通用
webkit.messageHandlers
(iOS)等——但 MAUI 封装后统一为
postMessage
调用。

在 XAML 或 C# 中启用 WebView 并订阅事件:
C# 端处理消息:

private void OnWebMessageReceived(object sender, WebMessageReceivedEventArgs e)
{
  string message = e.WebMessageAsJson; // 自动转为 JSON 字符串
  // 解析并响应,例如:
  if (message.Contains("getUserName"))
  {
    webView.PostWebMessageAsString(JsonSerializer.Serialize(new { result = "Alice" }));
  }
}

JS 端发送消息(网页中):
window.addEventListener("DOMContentLoaded", () => {
  window.chrome?.webview?.postMessage?.({ cmd: "getUserName" });
  // 或兼容写法(MAUI 内部会自动映射):
  if (typeof window.webkit !== 'undefined' && window.webkit.messageHandlers) {
    window.webkit.messageHandlers.external.postMessage({ cmd: "getUserName" });
  } else {
    window.chrome?.webview?.postMessage?.({ cmd: "getUserName" });
  }
});
注意:MAUI 的 WebView 在 Windows 上使用 WebView2,iOS 使用 WKWebView,JS 发送方式略有差异,但
PostWebMessageAsString
WebMessageReceived
在 C# 层已统一抽象,JS 端建议优先用
window.chrome?.webview?.postMessage
(MAUI 6+ 已注入兼容逻辑)。

Android/iOS 原生桥接(RegisterScriptableObject,有限支持)

该方式类似 Xamarin.Forms 的

RegisterScriptableObject
,但在 MAUI 中仅对 Android 和 iOS 有效(Windows/macOS 不支持),且需自定义
WebViewHandler
注入对象。

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

定义一个 C# 类并标记
[System.Runtime.InteropServices.ComVisible(true)]

[System.Runtime.InteropServices.ComVisible(true)]
public class JsBridge
{
  public string GetTime() => DateTime.Now.ToString();
  public void Log(string msg) => Debug.WriteLine($"JS said: {msg}");
}

在 Android 平台代码中(Platforms/Android/MainActivity.cs)注册:

var bridge = new JsBridge();
webView.Handler.PlatformView?.AddJavascriptInterface(bridge, "bridge");

JS 中调用:
bridge.GetTime(); // 注意大小写和括号
iOS 需配合
WKScriptMessageHandler
+
WKUserContentController
,实现更复杂,不推荐新手直接使用。

从 C# 主动调用 JS(反向通信)

无论用哪种 JS→C# 方式,C# 都可通过

WebView.EvaluateJavaScriptAsync
执行任意 JS 代码,实现反向调用:

例如通知网页加载完成:
await webView.EvaluateJavaScriptAsync("window.appReady && window.appReady();");
传递数据(需转义):
string data = JsonSerializer.Serialize(new { id = 123, name = "Test" });
await webView.EvaluateJavaScriptAsync($"window.receiveData({data});");
注意:JS 函数必须已在网页中全局定义,否则静默失败;建议加 try/catch 包裹 JS 端逻辑。

注意事项与避坑点

WebView 必须已加载完成(
NavigationCompleted
事件后)再注册监听或调用 JS,否则可能失效。
JSON 数据传输时,确保字符串合法,避免单引号、未转义换行等;建议统一用
JsonSerializer.Serialize
JsonSerializer.Deserialize
调试 JS→C# 通信:在 JS 中加
console.log
,C# 中加
Debug.WriteLine
,确认消息是否发出/收到。
不要依赖
window.external
(IE 时代遗留),MAUI 不支持;也不要尝试直接访问
window.bridge
除非你明确做了 Android 原生桥接。

基本上就这些。WebMessage 是最稳的起点,够用且可扩展;原生桥适合有特殊性能或深度集成需求的场景。不复杂但容易忽略加载时机和 JSON 格式细节。

相关推荐