Generare HTML a runtime a partire da un componente Razor in ASP.NET Core

di Marco De Sanctis, in ASP.NET Core,

In ASP.NET Core abbiamo a disposizione una semplice interfaccia per renderizzare programmaticamente un componente Razor. Pensiamo al caso in cui vogliamo per esempio comporre il testo HTML di una email, e abbiamo bisogno di un templating engine che ci permetta di generarlo a partire da un set di variabili.

Grazie a questa funzionalità, potremo utilizzare i componenti Razor e la loro sintassi familiare e intuitiva.

Immaginiamo di avere un Record che rappresenti un appuntamento di una clinica:

public record AppointmentDetails(
  string Email, 
  string Patient, 
  string DoctorName, 
  DateTime Day);

Il nostro obiettivo è quello di generare una mail di conferma a partire da questi dati. Iniziamo con la creazione di un componente Razor che chiameremo EmailTemplate:

<p>Dear @Appointment.Patient</p>

<p>We hope this email finds you well.</p>

<p>This email confirms your appointment with Dr.@Appointment.DoctorName
    for the next @Appointment.Day.ToShortDateString() </p>

@* .. altro testo qui .. *@

@code {
    [Parameter]
    public AppointmentDetails Appointment { get; set; }
}

Come possiamo notare, al di là del markup, abbiamo aggiunto un parametro di tipo AppointmentDetail, che ci aspettiamo di passare dall'esterno.

Da codice, possiamo eseguire il componente e generare l'HTML tramite la classe HtmlRenderer:

var renderer = new HtmlRenderer(_serviceProvider, _loggerFactory);

var html = await renderer.Dispatcher.InvokeAsync(async () =>
{
    var dictionary = new Dictionary<string, object?>
    {
        { "Appointment", appointment }
    };

    var parameters = Microsoft.AspNetCore
        .Components.ParameterView.FromDictionary(dictionary);
    var output = await renderer.RenderComponentAsync<EmailTemplate>(parameters);

    return output.ToHtmlString();
});

Per istanziare quest'oggetto, abbiamo bisogno di un IServiceProvider e di una ILoggerFactory, che possiamo iniettare tramite dependency injection. HtmlRenderer espone un metodo RenderComponentAsync, che però non possiamo invocare direttamente, a meno che non ci troviamo all'interno di un InvokeAsync del Dispatcher di ASP.NET Core.

Quindi, nel delegate che passiamo a InvokeAsync, non dobbiamo far altro che istanziare un dictionary con i parametri da passare (Appointment, nel nostro caso), e poi finalmente chiamare RenderComponentAsync, passando il tipo del template come generic.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi