【问题标题】:Evaluate and run a script with Blazor WASM使用 Blazor WASM 评估和运行脚本
【发布时间】:2021-02-22 05:25:05
【问题描述】:

我有一个在服务器上按预期工作的代码,它动态生成 C# 代码然后运行它。要运行代码,我使用以下代码:

string assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
MetadataReference[] references = new MetadataReference[]
{
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(RunResult).Assembly.Location),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Console.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.Extensions.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Collections.dll")),
    MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Text.Json.dll"))
};

var f =
    await CSharpScript.Create(
            code: code,
            options: ScriptOptions.Default.WithReferences(references))
        .ContinueWith<Func<RunResult, bool>>("new EvaluatorClass().Run")
        .CreateDelegate()
        .Invoke();

await using (MemoryStream ms = new MemoryStream())
{
    await using (StreamWriter currentOut = new StreamWriter(ms) { AutoFlush = true })
    {
        var runResult = f(codeResult);
    }
}

我已将此代码编写为 .NET Standard 库的一部分,现在我想使用 Blazor WebAssembly 在客户端运行它。

当我调试时,我发现问题在于 string assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location); 返回 null,因此(据我所知)不可能包含正在执行的代码所需的引用。

是否有其他方法可以实现这一点,以便在 Blazor 上运行?

【问题讨论】:

  • 您必须了解,任何 WASM 应用程序都完全运行在客户端,在 web 浏览器中。它在一个容器中。没有办法以这种方式访问​​本地文件系统(这将是一个很大的安全风险)。
  • @JHBonarius 我意识到了这一点。但我原以为作为 WASM 下载到浏览器的 .NET FW 可能会克服这种情况。
  • 我还尝试让这些 DLL 成为嵌入式资源并从流中获取 MetadataReference - 它再次在服务器上工作,但在 WASM 上工作,原因不明

标签: c# blazor blazor-webassembly blazor-client-side


【解决方案1】:

您可以尝试推断引用,而不是加载文件吗?

var scriptOptions = ScriptOptions.Default;
scriptOptions = scriptOptions.AddReferences(
    typeof(System.Object).GetTypeInfo().Assembly,
    typeof(System.Linq.Enumerable).GetTypeInfo().Assembly,
    /* don't know where `RunResult` comes from, add it yourself */);
scriptOptions = scriptOptions.AddImports(
    "System.Console",
    "System.Runtime",
    "System.Runtime.Extensions",
    "System.Collections",
    "System.Text.Json");

var f =
    await CSharpScript.Create(
            code: code,
            options: scriptOptions)
        [...etc...]

编辑:我用scriptOptions = scriptOptions.[...] 表示法进行了编辑。我不明白,但这似乎是人们在网上做的方式......这对我来说似乎是错误的。 edit2:好的,发现它ScriptOption 似乎在内部使用不可变数据结构。所以调用将(可能)返回一个新对象。

【讨论】:

  • 您好,感谢您的评论。我遇到了以下异常:System.NotSupportedException: Can't create a metadata reference to an assembly without location. - 我之前尝试将 DLL 作为嵌入式资源并从流中加载元数据会产生相同的错误。猜猜这不是 Blazor WASM 可以实现的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
相关资源
最近更新 更多