ForEach (Liquid) does't work
I have this code. This Name: {{Name }} works but not the for loop. What did I miss?
I am sending this from .NET core console app. (Not MVC, I don't need the layout file too)
var template = @"
Name: {{ Name }} <br/>
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{ item }}
{% endfor %}
";
SmtpClient client = new SmtpClient();
client.UseDefaultCredentials = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Host = smtpServer;
client.Port = 25;
FluentEmail.Core.Email.DefaultSender = new SmtpSender(client);
var options = new LiquidRendererOptions
{};
FluentEmail.Core.Email.DefaultRenderer = new LiquidRenderer(Options.Create(options));
await FluentEmail.Core.Email
.From(sender)
.To(reportingEmail)
.Subject(subject)
.UsingTemplate(template, model)
.SendAsync();
Had the same issue, documentation is non-existent but after trawling through the code you can use the following. Issue stems from the fact that Liquid is a secure language and by default it doesn't trust unknown classes.
var options = new LiquidRendererOptions
{
FileProvider = fileProvider,
ConfigureTemplateContext = (context, model) =>
{
context.MemberAccessStrategy = new UnsafeMemberAccessStrategy();
}
};
FluentEmail.Core.Email.DefaultRenderer = new LiquidRenderer(Microsoft.Extensions.Options.Options.Create(options));
public class UnsafeMemberAccessStrategy : IMemberAccessStrategy
{
public MemberNameStrategy MemberNameStrategy { get; set; } = MemberNameStrategies.Default;
private readonly MemberAccessStrategy baseMemberAccessStrategy = new MemberAccessStrategy();
public bool IgnoreCasing { get; set; }
public IMemberAccessor GetAccessor(Type type, string name)
{
var accessor = baseMemberAccessStrategy.GetAccessor(type, name);
if (accessor != null)
{
return accessor;
}
baseMemberAccessStrategy.Register(type, name);
return baseMemberAccessStrategy.GetAccessor(type, name);
}
public void Register(Type type, string name, IMemberAccessor getter)
{
baseMemberAccessStrategy.Register(type, name, getter);
}
}
@twisted89 thank you so much, battled with this for a whole day, how you found this solution is pure genius. I suspected this and created defined types thinking this would solve the problem:
Task SendEmailAsync<T>(string tag, string mailTo, string subject, string template, T model) where T : class;
public async Task SendEmailAsync<T>(string tag, string mailTo, string subject, string template, T model) where T : class
{
var path = Path.Combine($"{Directory.GetCurrentDirectory()}/EmailTemplates", template);
var res = await _fluentEmail
.To(mailTo)
.Tag(tag)
.Subject(subject)
.UsingTemplateFromFile<T>(path, model)
.SendAsync();
Console.WriteLine(res);
}
Raw data: {{ Alerts | json }} shows a json dump which means it works, but the values weren't being displayed, thanks once again