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 并订阅事件:
private void OnWebMessageReceived(object sender, WebMessageReceivedEventArgs e)
{
string message = e.WebMessageAsJson; // 自动转为 JSON 字符串
// 解析并响应,例如:
if (message.Contains("getUserName"))
{
webView.PostWebMessageAsString(JsonSerializer.Serialize(new { result = "Alice" }));
}
}
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}");
}
var bridge = new JsBridge();
webView.Handler.PlatformView?.AddJavascriptInterface(bridge, "bridge");
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 格式细节。
