MAUI中JS调用C#推荐使用WebMessage跨平台方案,通过WebView.WebMessageReceived事件接收消息、PostWebMessageAsync发送响应;Android/iOS可选RegisterScriptableObject但不跨平台;C#调JS统一用EvaluateJavaScriptAsync。

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 格式细节。










