You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过WASM在浏览器编译执行Blazor/.NET代码?搭建.NET在线代码平台

搭建无服务器.NET在线代码运行平台的解决方案

一、能否使用完整.NET WASM无服务器执行代码?

Blazor的AoT摇树优化确实会剔除未使用的库代码,但你可以获取完整的.NET WASM运行时包来支持任意C#代码的执行:

  • 完整的.NET WASM运行时包含了整个.NET类库的实现,体积通常在50-80MB左右,需要考虑前端加载的用户体验,可以通过预加载或分块加载优化。
  • 运行时本身只负责执行编译后的.NET程序集,无法直接编译C#代码,因此必须搭配前端编译器(即Roslyn WASM)才能实现“输入代码→编译→执行”的完整流程。

二、嵌入Roslyn WASM的入门指南

Roslyn提供了WebAssembly版本的编译器,完全可以在浏览器中完成C#代码的编译,以下是具体入门步骤:

1. 引入Roslyn WASM资源

在你的前端项目(无论是纯JS还是Blazor)中,引入Roslyn的WASM编译包,可以通过NuGet安装Microsoft.CodeAnalysis.CSharp.WebAssembly,或者直接使用编译后的静态资源文件(Roslyn.csharp.wasm及配套JS绑定)。

2. 基础编译流程

核心是调用Roslyn的编译API生成程序集字节码,再通过.NET WASM运行时加载执行:

  • 创建语法树:将输入的C#代码字符串解析为Roslyn语法树。
  • 配置编译选项:指定输出类型(如动态链接库)、目标框架版本(需与WASM运行时版本匹配)。
  • 添加程序集引用:必须包含代码中用到的.NET类库引用(如System.Runtime、System.Core等,可从WASM运行时的dll文件中获取)。
  • 执行编译:生成程序集字节流,处理编译错误。

3. 简化示例代码(Blazor环境)

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
using System.IO;

public async Task<string> RunDynamicCode(string csharpCode)
{
    // 1. 解析代码为语法树
    var syntaxTree = CSharpSyntaxTree.ParseText(csharpCode);

    // 2. 设置编译参数
    var compilationOpts = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
        .WithTargetFramework("net8.0"); // 匹配你的WASM运行时版本

    // 3. 添加必要的程序集引用
    var references = new List<MetadataReference>
    {
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(Task).Assembly.Location)
    };

    // 4. 创建编译对象并执行编译
    var compilation = CSharpCompilation.Create("DynamicCodeAssembly")
        .WithOptions(compilationOpts)
        .AddSyntaxTrees(syntaxTree)
        .AddReferences(references);

    using var ms = new MemoryStream();
    var emitResult = compilation.Emit(ms);

    // 处理编译错误
    if (!emitResult.Success)
    {
        var errorMessages = string.Join("\n", emitResult.Diagnostics
            .Where(d => d.Severity == DiagnosticSeverity.Error)
            .Select(d => $"Error: {d.GetMessage()}"));
        return $"Compilation failed:\n{errorMessages}";
    }

    // 5. 加载程序集并执行指定方法
    ms.Seek(0, SeekOrigin.Begin);
    var assembly = Assembly.Load(ms.ToArray());
    var targetType = assembly.GetType("DynamicRunner"); // 假设代码中包含这个类
    var runMethod = targetType.GetMethod("Execute", BindingFlags.Public | BindingFlags.Static);
    var result = runMethod?.Invoke(null, null);

    return result?.ToString() ?? "Execution returned no result";
}

注意:输入的代码需要包含一个可执行的入口,比如public class DynamicRunner { public static string Execute() { /* 你的代码逻辑 */ } }

4. 关键注意事项

  • 版本匹配:Roslyn WASM的版本必须与.NET WASM运行时版本一致,否则会出现兼容性问题。
  • 引用管理:如果代码用到了更多.NET类库(如System.Drawing),需要额外添加对应的程序集引用。
  • 性能优化:编译过程在浏览器中执行,复杂代码会耗时较长,可以添加加载提示;同时可以缓存常用的程序集引用提升重复编译速度。

总结

要实现类似jsfiddle的.NET在线运行平台,核心是Roslyn WASM负责前端编译 + 完整.NET WASM运行时负责代码执行。入门时先从简单的代码编译执行开始,逐步扩展支持更多.NET库和Blazor组件(Blazor组件的执行需要额外处理渲染逻辑,比如动态创建组件并挂载到DOM)。

内容的提问来源于stack exchange,提问作者Luke Vo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:15:00