导读:本期聚焦于小伙伴创作的《如何实现C#代码与JavaScript函数的相互调用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何实现C#代码与JavaScript函数的相互调用》有用,将其分享出去将是对创作者最好的鼓励。

在混合应用开发、桌面端嵌入网页等场景中,C#代码和JavaScript函数的相互调用是非常常见的需求,不同技术栈下的实现方式存在差异,下面分别介绍主流的实现方案。

如何实现C#代码与JavaScript函数的相互调用

C#调用JavaScript函数

桌面端基于WebBrowser控件(WinForms/WPF)

WinForms或WPF中如果使用WebBrowser控件加载网页,可以通过控件的Document.InvokeScript方法调用页面中的JavaScript函数。

首先前端页面需要定义对应的JavaScript函数:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>测试页面</title>
</head>
<body>
    <script type="text/javascript">
        // 供C#调用的JavaScript函数
        function showMessage(msg) {
            alert("来自C#的消息:" + msg);
            return "JS已收到消息";
        }
    </script>
</body>
</html>

然后C#端调用该函数的代码如下:

// WinForms中WebBrowser控件调用JS函数示例
private void CallJsFunction()
{
    // 假设webBrowser1已经加载了上面的HTML页面
    if (webBrowser1.Document != null)
    {
        // 调用名为showMessage的JS函数,传入参数
        object result = webBrowser1.Document.InvokeScript("showMessage", new object[] { "Hello from C#" });
        // 输出JS函数的返回值
        MessageBox.Show("JS返回结果:" + result?.ToString());
    }
}

Web端基于Blazor框架

Blazor提供了JS互操作服务,可以便捷地调用JavaScript函数。首先在页面中定义JS函数:

<script>
    // 供Blazor调用的JS函数
    window.blazorJsFunctions = {
        showAlert: function (message) {
            alert(message);
            return "JS处理完成";
        },
        calculateSum: function (a, b) {
            return a + b;
        }
    };
</script>

C#端注入IJSRuntime服务后调用JS函数:

using Microsoft.JSInterop;
using System.Threading.Tasks;

public class JsCallService
{
    private readonly IJSRuntime _jsRuntime;

    public JsCallService(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    // 调用无返回值的JS函数
    public async Task CallAlert()
    {
        await _jsRuntime.InvokeVoidAsync("blazorJsFunctions.showAlert", "Blazor调用JS成功");
    }

    // 调用有返回值的JS函数
    public async TaskCallCalculate()
    {
        int result = await _jsRuntime.InvokeAsync("blazorJsFunctions.calculateSum", 10, 20);
        return result;
    }
}

JavaScript调用C#函数

桌面端基于WebBrowser控件

需要将C#的对象暴露给JavaScript环境,通过设置WebBrowser控件的ObjectForScripting属性实现。

首先定义需要暴露给JS的C#类,需要标记ComVisible特性:

using System.Runtime.InteropServices;
using System.Windows.Forms;

[ComVisible(true)] // 必须标记为ComVisible,否则JS无法访问
public class JsBridge
{
    // 供JS调用的C#方法
    public string HandleJsMessage(string message)
    {
        MessageBox.Show("收到JS消息:" + message);
        return "C#已处理你的消息";
    }

    public int Add(int a, int b)
    {
        return a + b;
    }
}

然后在窗体中设置ObjectForScripting

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        // 将JsBridge实例暴露给JS环境,JS中可以通过window.external访问
        webBrowser1.ObjectForScripting = new JsBridge();
        // 加载测试页面
        webBrowser1.Navigate("test.html");
    }
}

前端JavaScript调用C#方法的代码:

// 调用C#暴露的方法
function callCSharp()
{
    // window.external对应C#设置的ObjectForScripting实例
    var result = window.external.HandleJsMessage("Hello from JS");
    alert("C#返回结果:" + result);
    
    var sum = window.external.Add(5, 3);
    alert("5+3的结果是:" + sum);
}

Web端基于Blazor框架

Blazor中可以让JavaScript调用C#的静态方法或者组件实例方法,需要给方法标记[JSInvokable]特性。

首先定义可被JS调用的C#方法:

using Microsoft.JSInterop;
using System.Threading.Tasks;

public class CSharpFunctions
{
    // 标记JSInvokable特性,指定JS中调用的函数名
    [JSInvokable("handleJsCall")]
    public static string HandleJsCall(string message)
    {
        return $"C#收到JS的消息:{message},处理完成";
    }

    [JSInvokable]
    public static int Multiply(int a, int b)
    {
        return a * b;
    }
}

JavaScript中调用C#方法的代码:

// 调用C#静态方法
async function callCSharpStatic() {
    // 调用带指定名称的JSInvokable方法
    const result1 = await DotNet.invokeMethodAsync('YourAssemblyName', 'handleJsCall', 'JS调用测试');
    alert(result1);
    
    // 调用默认方法名的JSInvokable方法,方法名和C#方法名一致
    const result2 = await DotNet.invokeMethodAsync('YourAssemblyName', 'Multiply', 4, 6);
    alert('4*6的结果是:' + result2);
}

如果是调用Blazor组件实例的方法,需要先给组件实例生成引用,再传递给JS:

@page "/js-call"
@using Microsoft.JSInterop
@implements IDisposable

<button @onclick="TriggerJsCall">触发JS调用C#实例方法</button>

@code {
    private DotNetObjectReference<JsCallComponent>? objRef;

    [JSInvokable]
    public string InstanceMethod(string msg)
    {
        return $"组件实例收到消息:{msg}";
    }

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public void Dispose()
    {
        objRef?.Dispose();
    }

    // 将组件引用传递给JS
    public async Task TriggerJsCall()
    {
        await JSRuntime.InvokeVoidAsync("callCSharpInstance", objRef);
    }
}

对应的JS代码:

function callCSharpInstance(dotNetRef) {
    // 调用组件实例的JSInvokable方法
    dotNetRef.invokeMethodAsync('InstanceMethod', '来自JS的实例调用')
        .then(result => alert(result));
}

注意事项

  • 桌面端WebBrowser控件基于IE内核,对现代JavaScript语法支持有限,如需使用新特性建议更换为WebView2控件,调用方式类似但接口有差异。
  • Blazor的JS互操作中,调用异步JS函数时需要使用对应的异步方法,避免阻塞线程。
  • 暴露给JavaScript的C#方法需要注意权限控制,避免未授权的调用造成安全问题。
  • 跨语言调用时参数类型需要匹配,比如C#的int对应JS的number,string对应JS的string,复杂对象需要序列化和反序列化处理。

C#JavaScript相互调用WebBrowserJS互操作修改时间:2026-06-02 22:03:02

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。