Search code examples
c#razor-pagesasp.net-core-3.1blazor-server-side

How to send a razor component as body in an email using Blazor and NetCore 5?


How can I send a razor component in the body of an email using Blazor Server Side and NetCore 5 ? In MVC I always used the RenderPartialViewToString() but I have no clue how to do it in Blazor.

NOTE: The question is not about how to send email using Blazor but how to include the razor page in the body of the email.

// This is the code to send email. Works fine.
MimeMessage message = new MimeMessage();
MailboxAddress from = new MailboxAddress(model.FromName, model.FromAddress); message.From.Add(from);
MailboxAddress to = new MailboxAddress(model.ToName, model.ToAddress); message.To.Add(to);
message.Subject = model.Subject;

// Add email body and file attachments
BodyBuilder bodyBuilder = new BodyBuilder();
bodyBuilder.HtmlBody = model.Body;
//bodyBuilder.TextBody = "Hello World!";
message.Body = bodyBuilder.ToMessageBody();

//Connect and authenticate with the SMTP server
using (SmtpClient smtpClient = new SmtpClient())
{
   await InvokeAsync(() => { ShowSpinner = true; StateHasChanged(); });
   await smtpClient.ConnectAsync(model.SmtpServer, model.Port, true);
   await smtpClient.AuthenticateAsync(model.Username, model.Password);
   // Send email message
   await smtpClient.SendAsync(message);
   await InvokeAsync(() => { ShowSpinner = false; SuccessAlertMsg = "The email has been sent!"; StateHasChanged(); });
   await smtpClient.DisconnectAsync(true);
}

Solution

  • It seems you're really just asking how to get the html, not how to build an e-mail, right? I think JS Interop will do it easily. You can put the @ref on any item you want, mine is just garbage test data.

    GetHTML.js

    window.getDivContents = (element) => {
        return element.innerHTML;
    }
    

    Page.razor

    <div @ref="Ref">
        @{
            Random rand = new Random();
            int imax = rand.Next(4) + 1;
            for (int i = 0; i < imax; i++)
            {
                int jmax = rand.Next(3) + 1;
                <ul>
                    @for (int j = 0; j < jmax; j++)
                    {
                        <li>List @(i+1), Item @(j+1): #@Guid.NewGuid()</li>
                    }
                </ul>
            }
        }
    </div>
    <button @onclick="GetHTML">Get HTML</button>
    <div>
        @HTML
    </div>
    
    @code {
        ElementReference Ref { get; set; }
        string HTML { get; set; } = "";
        async Task GetHTML()
        {
            HTML = new(await JS.InvokeAsync<string>("getDivContents", Ref));
        }
    }