microsoft/ClearScript

How to use Linq in jsondata in microsoft.clearscript.v8

Closed this issue · 4 comments

in this case I am use microsoft.clearscript.v8 in asp .net core mvc
this is below homecontroller.cs code

  `        
                public IActionResult Index()
                 {
        
           using (var engine = new V8ScriptEngine())

           {

            string json = @"
    [
        { ""id"": 1, ""name"": ""John"", ""age"": 25 },
        { ""id"": 2, ""name"": ""Jane"", ""age"": 30 }      
    ]";

            // Parse JSON as JArray
            var jsonArray = JArray.Parse(json);

            // Use ClearScript to filter the data
            engine.Script.PersonList = jsonArray.ToObject<List<dynamic>>();
            engine.AddHostType(typeof(Enumerable));
            engine.AddHostType("Pred", typeof(Func<dynamic, bool>));

            engine.Execute(@"
            var result = PersonList.Where(new Pred(p => p.age > 25)).ToList();
        ");

            // Retrieve the result from the script engine
            List<dynamic> filteredList = engine.Script.result;

            // Print filtered results
            foreach (var person in filteredList)
            {
                Console.WriteLine($"Id: {person.id}, Name: {person.name}, Age: {person.age}");
            }
        }
     return view();
    }

`

Hello @Ommkwn2001,

Consider this line in your code:

var result = PersonList.Where(new Pred(p => p.age > 25)).ToList();

The expression p.age returns a JValue instance, which isn't comparable to a number in JavaScript. The age comparison always evaluates to false.

The same comparison works in C# because JValue implements special support for dynamic. Unfortunately, V8 doesn't allow the host to overload JavaScript's comparison operators.

One way to make it work is by explicitly invoking the Value property:

var result = PersonList.Where(new Pred(p => p.age.Value > 25)).ToList();

Another possibility is to use an extension method to implement valueOf for JValue:

public static class JValueExtensions {
    public static object valueOf(this JValue value) => value.Value;
}

And then:

engine.AddHostType(typeof(JValueExtensions));
engine.Execute(@"
    var result = PersonList.Where(new Pred(p => p.age > 25)).ToList();
");

Good luck!

in this case I am use microsoft.clearscript.v8 in asp .net core mvc
this is below homecontroller.cs code,
when i debug the code the resultJson = [] and the filteredProducts's count = 0,
so how to field name change and get new json with changes

      `          using (var engine = new V8ScriptEngine())
           {

            string additionalJson = @"
                            {
                                ""Account"": {
                                    ""AccountName"": ""Firefly"",
                                    ""Order"": [
                                        {
                                            ""OrderID"": ""order103"",
                                            ""Product"": [
                                                {
                                                    ""ProductName"": ""Bowler Hat"",
                                                    ""ProductID"": 858383,
                                                    ""Price"": 34.45,
                                                    ""Quantity"": 2
                                                },
                                                {
                                                    ""ProductName"": ""Trilby hat"",
                                                    ""ProductID"": 858236,
                                                    ""SKU"": ""0406634348"",
                                                    ""Price"": 21.67,
                                                    ""Quantity"": 1
                                                }
                                            ]
                                        },
                                        {
                                            ""OrderID"": ""order104"",
                                            ""Product"": [
                                                {
                                                    ""ProductName"": ""Bowler Hat"",
                                                    ""ProductID"": 858383,
                                                    ""SKU"": ""040657863"",
                                                    ""Price"": 34.45,
                                                    ""Quantity"": 4
                                                },
                                                {
                                                    ""ProductID"": 345664,
                                                    ""SKU"": ""0406654603"",
                                                    ""ProductName"": ""Cloak"",
                                                    ""Price"": 107.99,
                                                    ""Quantity"": 1
                                                }
                                            ]
                                        }
                                    ]
                                }
                            }";


            // Parse JSON as JObject
            var jsonObject = JObject.Parse(additionalJson);

            // Use ClearScript to filter the data
            engine.Script.ProductList = jsonObject["Account"]["Order"]
                .SelectMany(order => order["Product"].ToObject<List<dynamic>>())
                .ToList();

            engine.AddHostType(typeof(Enumerable));
            engine.AddHostType("Pred", typeof(Func<dynamic, bool>));

            engine.Execute(@"
   var result = [];
    for (var i = 0; i < ProductList.length; i++) {
    var product = ProductList[i];
     result.push({ ProductN: product.ProductName });
   }
     var resultJson = JSON.stringify(result);
     resultJson;
       ");

                string resultJson = engine.Evaluate("resultJson") as string;

            // Check if the resultJson is not null or empty
            if (!string.IsNullOrEmpty(resultJson))
            {
                // Deserialize the JSON into a list
                List<dynamic> filteredProducts = JsonConvert.DeserializeObject<List<dynamic>>(resultJson);

                // Print filtered results
                foreach (var product in filteredProducts)
                {
                    Console.WriteLine($"ProductN: {product.ProductN}");
                }
            }
            else
            {
                Console.WriteLine("No data found in resultJson.");
                       }     
`

Regarding this JavaScript code:

for (var i = 0; i < ProductList.length; i++) {
    var product = ProductList[i];
    result.push({ ProductN: product.ProductName });
}

Since ProductList is a .NET list, it has no length property. Try Count instead.

Cheers!

Please reopen this issue if you have additional questions or comments about this topic. Thank you!