I'm struggling to make email work while working with embedded resource for _Layout.cshtml in FluentEmail.
This is the exception error I'm getting:
Project can not find template with key _Layout.cshtml
This is my setup so far:
Inside the ConfigureServices in Program.cs, I've added the RazorRenderer as:
//Set email service using FluentEmail
services.AddFluentEmail("[email protected]")
.AddRazorRenderer(typeof(Program))
.AddSmtpSender("smtp.somesmtp.com", 25)
.AddSmtpSender(new System.Net.Mail.SmtpClient() { });
Inside my NotificationService.cs, I always fall into that exception block:
private async Task SendEmailAsync<TModel>(string subject, TModel model)
{
try
{
using (var scope = _serviceProvider.CreateScope())
{
var email = await scope.ServiceProvider.GetRequiredService<IFluentEmail>()
.To(string.Join(";", _emailRecipients))
.Subject(subject)
.UsingTemplateFromEmbedded("AppName.Views.Emails.SomeReport.cshtml", model, GetType().Assembly)
.SendAsync();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to send email. Check exception for more information.");
}
}
SomeReport.cshtml is inside Views\Emails\SomeReport.cshtml which looks like this:
@using System;
@using RazorLight;
@using System.Collections.Generic;
@using AppName.Models;
@inherits TemplatePage<IEnumerable<SomeReport>>
@{
@* For working with Embedded Resource Views *@
Layout = "_Layout.cshtml";
}
@* Work with the Model here... *@
_Layout.cshtml is inside Views\Shared\_Layout.cshtml which looks like this:
@using RazorLight;
@* Some common layout styles here *@
@RenderBody()
Both the SomeReport.cshtml and _Layout.cshtml are Embedded resources:
My references has RazorLight through FluentEmail.Razor package.
If it helps, this is a .NET 5 Worker Service project and I've also added PreserveCompilationContext and PreserveCompilationReferences in the .csproj file:
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<PreserveCompilationReferences>true</PreserveCompilationReferences>
</PropertyGroup>
I've looked at everywhere and still haven't found a solution to this. Something this simple has been such a struggle to make work. Please help.
Thanks!
TL;DR
Point to Note 1:
Specifying the path to
_Layout.cshtmlin your Views must be relative to the embedded resource root you enter while adding FluentEmail. For eg:Since my
Program.csandViewsfolder are in the same level, to locate_Layout.cshtmlbySomeReport.cshtml, my path needs to be:Point to Note 2:
Specifying the path to your View needs to be the full path starting from your Assembly name. For eg:
It works like a charm now!
My full setup
Inside the
ConfigureServicesmethod inProgram.cs-->Inside my
FluentEmailService.cs:The properties of my Views (
SomeReport.cshtml,_Layout.cshtml) look like this:(You don't need to do this for
_ViewImports.cshtmland_ViewStart.cshtml.)My View
SomeReport.cshtmlis insideViews\Emails\SomeReport.cshtmland looks like this:_Layout.cshtmlis insideViews\Shared\_Layout.cshtmlwhich looks like this:My references has
RazorLightthroughFluentEmail.Razorpackage.The settings for Razorlight looks like this in my .csproj file: