# Att skicka HTML-email från ASP.NET Core med FluentEmail

<datetime class="hidden">2024-08-07T00:30</datetime>

<!--category-- ASP.NET, FluentEmail -->
Det här är en ganska enkel artikel men den kommer beskriva [FluentEmail](https://github.com/lukencode/FluentEmail) i ASP.NET Core för att skicka HTML e-mail jag har inte sett

## Problemet

Att skicka HTML-poster är i sig själv ganska enkelt med SmtpClient, men det är inte särskilt flexibelt och det stödjer inte saker som szabloner eller anhängningar. FluentEmail är en bra bibliotek för detta.

FluentEmail med Razorlight (it ' som är inbyggd i) låter dig forma dina e-poster med hjälp av Razor syntaxenM SK3 Det här är jättebra eftersom det låter dig använda fulla kraften från Razor för att skapa era e-mail

## Lösningen

Först och främst måste du installera FluentEmail.Core, FluentemailM SK3Smtp Mska4 Fluen EmailMske5Razor bibliotek

```bash
dotnet add package FluentEmail.Core
dotnet add package FluentEmail.Smtp
dotnet add package FluentEmail.Razor
```

## Att sätta upp FluentEmail

För att hålla saker separat skapade jag en IServiceCollection-extension som installerar FluentEmail-tjänsterna:

```csharp
namespace Mostlylucid.Email;

public static class Setup
{
    public static void SetupEmail(this IServiceCollection services, IConfiguration config)
    {
          var smtpSettings = services.ConfigurePOCO<SmtpSettings>(config.GetSection(SmtpSettings.Section));

        services.AddFluentEmail(smtpSettings.SenderEmail, smtpSettings.SenderName)
            .AddRazorRenderer();

        services.AddSingleton<ISender>(new SmtpSender( () => new SmtpClient()
        {
            DeliveryMethod = SmtpDeliveryMethod.Network,
            Host = smtpSettings.Server,
            Port = smtpSettings.Port,
            Credentials = new NetworkCredential(smtpSettings.Username, smtpSettings.Password),
            EnableSsl = smtpSettings.EnableSSL,
            UseDefaultCredentials = false
        }));
        services.AddSingleton<EmailService>();
        
    }

}
```

##SMTP Settings

Som ni ser i ' använde jag också metoden IConfigSection som nämns i min [tidigare artikel](blog/addingidentityfreegoogleauth#configuring-google-auth-with-poco) att få de SMTP-inställningarna.

```csharp
  var smtpSettings = services.ConfigurePOCO<SmtpSettings>(config.GetSection(SmtpSettings.Section));
```

Det här kommer från appsettings

```json
"SmtpSettings":
  {
    "Server": "smtp.gmail.com",
    "Port": 587,
    "SenderName": "Mostlylucid",
    "Username": "",
    "SenderEmail": "scott.galloway@gmail.com",
    "Password": "",
    "EnableSSL": "true",
    "EmailSendTry": 3,
    "EmailSendFailed": "true",
    "ToMail": "scott.galloway@gmail.com",
    "EmailSubject": "Mostlylucid"
    
  }
```

## GMAIL / Google SMTP

Nota: För Google SMTP om du använder MFA ( som du **verkligen* om du [app-passwort för ditt konto](https://myaccount.google.com/apppasswords).

För den lokala dev, kan du lägga till det här i dina hemligheter.json fileM SK2

![secrets.png](secrets.png)

### Dockeruppstelling

För docker-komposer använder du normalt sett: 'd inkludera detta i en ♫ . ♫ env ♫ file

```env
SMTPSETTINGS_USERNAME="scott.galloway@gmail.com"
SMTPSETTINGS_PASSWORD="<MFA PASSWORD>" -- this is the app password you created

```

Sedan injicerar du dessa i dockerkompositionsfilet som env-variabler:

```yaml
services:
  mostlylucid:
    image: scottgal/mostlylucid:latest
    ports:
      - 8080:8080
    environment:
      - SmtpSettings__UserName=${SMTPSETTINGS_USERNAME}
      - SmtpSettings__Password=${SMTPSETTINGS_PASSWORD}
```

Ta en notation av utrymmet eftersom det verkligen kan förvirra dig med docker compose. För att kolla vad

```bash
docker compose config
```

För att visa er hur filet ser ut med dessa injicerade.

## FluentEmail-Annonanser

Ett problem med Fluent Email är att du behöver lägga till det här i csproj

```xml
  <PropertyGroup>
    <PreserveCompilationContext>true</PreserveCompilationContext>
  </PropertyGroup>
```

Det beror på att FluentEmail använder RazorLight som behöver det här för att fungera.

För szablonerna, kan du antingen inkludera dem i ditt projekt som innehållsdater eller som jag gör i dockercontainern, kopiera dem till slutmålet

```yaml
FROM build AS publish
RUN dotnet publish "Mostlylucid.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app

COPY --from=publish /app/publish .
# Copy the Markdown directory
COPY ./Mostlylucid/Markdown /app/Markdown
COPY ./Mostlylucid/Email/Templates /app/Email/Templates
# Switch to a non-root user
USER $APP_UID
```

## E-posttjänster

Ok tillbaka till koden!

Nu har vi allt klart så kan vi lägga till e-posttjänsterna

```csharp
public class EmailService(SmtpSettings smtpSettings, IFluentEmail fluentEmail)
{
    public async Task SendCommentEmail(string commenterEmail, string commenterName, string comment, string postSlug)
    {
        var commentModel = new CommentEmailModel
        {
            PostSlug = postSlug,
            SenderEmail = commenterEmail,
            SenderName = commenterName,
            Comment = comment
        };
        await SendCommentEmail(commentModel);
    }

    public async Task SendCommentEmail(CommentEmailModel commentModel)
    {
        // Load the template
        var templatePath = "Email/Templates/MailTemplate.template";
        await SendMail(commentModel, templatePath);
    }

    public async Task SendContactEmail(ContactEmailModel contactModel)
    {
        var templatePath = "Email/Templates/ContactEmailModel.template";

        await SendMail(contactModel, templatePath);
    }


    public async Task SendMail(BaseEmailModel model, string templatePath)
    {
        var template = await File.ReadAllTextAsync(templatePath);
        // Use FluentEmail to send the email
        var email = fluentEmail.UsingTemplate(template, model);
        await email.To(smtpSettings.ToMail)
            .SetFrom(smtpSettings.SenderEmail, smtpSettings.SenderName)
            .Subject("New Comment")
            .SendAsync();
    }
}
```

Som ni kan se här har vi två metoder, ett för kommentarer och ett för Kontaktformular ([skicka ett brev till mig!](/contact) ). I den här appen får jag dig att logga in så att jag kan få posten från det,

Den verkliga största delen av arbetet görs här.

```csharp
 var template = await File.ReadAllTextAsync(templatePath);
        // Use FluentEmail to send the email
        var email = fluentEmail.UsingTemplate(template, model);
        await email.To(smtpSettings.ToMail)
            .SetFrom(smtpSettings.SenderEmail, smtpSettings.SenderName)
            .Subject("New Comment")
            .SendAsync();
```

Här öppnar vi en modellfiled, lägger till modellen som innehåller innehållet för e-mailn , ladda upp den i FluentEmail och sen skicka den. Vorlagen är en enkel Razor-Datei

```razor
@model Mostlylucid.Email.Models.ContactEmailModel

<!DOCTYPE html>
<html class="dark">
<head>
    <title>Comment Email</title>
</head>
<body>
<h1>Comment Email</h1>
<p>New comment from email @Model.SenderEmail name @Model.SenderName</p>

<p>Thank you for your comment on our blog post. We appreciate your feedback.</p>
<p>Here is your comment:</p>
<div>
    @Raw( @Model.Comment)</div>
<p>Thanks,</p>
<p>The Blog Team</p>

</body>
</html>
```

De lagras som .template-filer i E-posten/Templates-ordnetM SK2 Du kan använda .cshtml-filar men det orsakar ett problem med | @ | Rasieretikett i szablonen |( | it | МSK6 | det är en Rasierduks grej

## Kontrollören

Till slut kommer vi till kontrollen. ;, det är rätt enkelt.

```csharp
    [HttpPost]
    [Route("submit")]
    [Authorize]
    public async Task<IActionResult> Submit(string comment)
    {
        var user = GetUserInfo();
            var commentHtml = commentService.ProcessComment(comment);
            var contactModel = new ContactEmailModel()
            {
                SenderEmail = user.email,
                SenderName =user.name,
                Comment = commentHtml,
            };
            await emailService.SendContactEmail(contactModel);
            return PartialView("_Response", new ContactViewModel(){Email = user.email, Name = user.name, Comment = commentHtml, Authenticated = user.loggedIn});

        return RedirectToAction("Index", "Home");
    }
```

Här får vi användarinformationen, bearbeta kommentareret ( Jag använder en enkel markerdown-processor med Markdig för att konvertera markerdown till HTMLM SK2 och sen skickar jag in e-mailn