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

ASP.NET Core MVC中Microsoft.ClearScript.V8的LINQ使用及报错解决

在ASP.NET Core MVC中使用ClearScript V8获取JS返回结果并使用LINQ

问题场景

在ASP.NET Core MVC项目中使用Microsoft.ClearScript.V8执行JS脚本,调用NewLinq()返回过滤后的数组时,触发以下错误:

UnderlyingSystemType = '((Microsoft.ClearScript.ScriptItem)data).UnderlyingSystemType' threw an exception of type 'System.NotImplementedException'

原控制器代码:

public async Task<IActionResult> Index()
{
    using (var engine1 = new V8ScriptEngine())
    {
        engine1.AddHostType(typeof(JavaScriptExtensions));
        engine1.DocumentSettings.AccessFlags = DocumentAccessFlags.EnableFileLoading;
        string scriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "js", "NewScript.js");
        string scriptContent = System.IO.File.ReadAllText(scriptPath);
        engine1.Execute(scriptContent);
        dynamic data = engine1.Evaluate("NewLinq();");
        return View();
    }
}

JS脚本NewScript.js代码:

function NewLinq() {
  const rawData = [
    { "id": 1, "name": "John", "age": 25 },
    { "id": 2, "name": "Jane", "age": 30 }      
  ];

  var result = rawData.filter(person => person.age > 25);  
  return result;
}

错误原因

ClearScript返回的dynamic对象是V8引擎的脚本对象包装,并非原生CLR集合类型,直接访问其内部属性或尝试用LINQ操作会触发未实现的异常。

解决方案

需要将V8返回的脚本对象显式转换为CLR可识别的集合类型,推荐两种实现方式:

方式1:强类型转换(推荐,便于LINQ操作)

  1. 定义对应JS对象的实体类:
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
  1. 修改控制器代码,转换为强类型集合:
public async Task<IActionResult> Index()
{
    using (var engine1 = new V8ScriptEngine())
    {
        engine1.AddHostType(typeof(JavaScriptExtensions));
        engine1.DocumentSettings.AccessFlags = DocumentAccessFlags.EnableFileLoading;
        string scriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "js", "NewScript.js");
        string scriptContent = System.IO.File.ReadAllText(scriptPath);
        engine1.Execute(scriptContent);
        
        // 将V8脚本数组转换为CLR可枚举类型
        var scriptResult = engine1.Evaluate("NewLinq();") as IEnumerable<dynamic>;
        
        // 转换为强类型集合
        var personList = scriptResult.Select(item => new Person
        {
            Id = (int)item.id,
            Name = (string)item.name,
            Age = (int)item.age
        }).ToList();
        
        // 正常使用LINQ操作
        var filteredPersons = personList.Where(p => p.Age >= 30).ToList();
        
        return View(filteredPersons);
    }
}

方式2:使用ScriptObject直接处理

如果不需要强类型,也可以通过ScriptObject访问属性并转换:

public async Task<IActionResult> Index()
{
    using (var engine1 = new V8ScriptEngine())
    {
        engine1.AddHostType(typeof(JavaScriptExtensions));
        engine1.DocumentSettings.AccessFlags = DocumentAccessFlags.EnableFileLoading;
        string scriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "js", "NewScript.js");
        string scriptContent = System.IO.File.ReadAllText(scriptPath);
        engine1.Execute(scriptContent);
        
        var scriptArray = engine1.Evaluate("NewLinq();") as ScriptObject;
        var dataList = new List<dynamic>();
        
        foreach (var item in scriptArray)
        {
            var person = new
            {
                Id = (int)((ScriptObject)item)["id"],
                Name = (string)((ScriptObject)item)["name"],
                Age = (int)((ScriptObject)item)["age"]
            };
            dataList.Add(person);
        }
        
        // LINQ操作示例
        var result = dataList.Where(p => p.Age > 25).ToList();
        
        return View(result);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:52:35