adoconnection / RazorEngineCore

.NET6 Razor Template Engine
MIT License
565 stars 84 forks source link

run linq lambdas inside template seems to have problems #127

Open Shay-da opened 1 year ago

Shay-da commented 1 year ago

Hey :) I need to update our old razorEngine to a new one- while most of our templats run fine- we have a few template which are a bit more complex. when running template with the following code-

foreach (var field in Model.Fields.Where(f => !String.IsNullOrEmpty(f.Label) && f.Label.Equals("Some Text", StringComparison.OrdinalIgnoreCase)))

this worked fine with the old razor engine.. with the new one we get-the following error:

Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.

so after pulling the enumarator logic and assign it outside (in our example lets say - var fields = Model.Fields...) the linq query we faced another error- 'System.Collections.Generic.List' does not contain a definition for 'FirstOrDefault' although we added @using System.Linq in the cshtml file and also while creating the template we inject System.Core, Version=4.0.0.0 assembly to make sure its not dll issues.. any idea if we are in the right direction or im missing something?

adoconnection commented 1 year ago

Hi! If fields is a dynamic property you need to cast it to List/Enumerable first see TestCompileAndRun_DynamicModelLinq unit test https://github.com/adoconnection/RazorEngineCore/blob/c6ff4880e6a31332d16006e2fdc043f10ebbfa78/RazorEngineCore.Tests/TestCompileAndRun.cs#L620

GreenIreland commented 1 year ago

Hi! I got same issue with lambdas.

Razor code: @{ var wallet = (IEnumerable<object>)(Model.Guest.UserWallets).Where(uw => uw.Wallet.IsActive).Single(); }

UserWallets is IList property. Wallet.IsActive is boolean property.

Result: CS1977 error - Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.

@{ var wallet = (IEnumerable<object>)(Model.Guest.UserWallets).Single(); } works well.

@adoconnection Any ideas how to fix this / how to use lambda expressions?