Neu in .NET 8.0 [19]: Razor-HTML-Rendering in beliebigen .NET-Anwendungen

Das HTML-Rendern mit Razor-Komponenten ist in .NET 8.0 auch außerhalb von Blazor-Anwendungen möglich, beispielsweise für HTML-formatierte E-Mails.

In Pocket speichern vorlesen Druckansicht
Mail-Symbol

(Bild: Pavel Ignatov/Shutterstock.com)

Lesezeit: 2 Min.
Von
  • Dr. Holger Schwichtenberg

Die Razor-Template-Syntax hat Microsoft schon im Jahr 2010 vorgestellt und in ASP.NET MVC Classic Version 3 am 13.11.2011eingeführt, siehe Blogeintrag von Scott Guthrie vom 3.7.2010. Sie wurde auch in ASP.NET Webpages verwendet und später in ASP.NET Core MVC und ASP.NET Core Razor Pages übernommen. In Blazor gibt es eine erweiterte Version mit einem vereinfachten Modell für wiederverwendbare Razor-Komponenten.

Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

Das Rendern der in Blazor verwendeten Razor-Komponenten ist in .NET 8.0 auch außerhalb von Blazor-Anwendungen möglich. Somit steht die gleiche Syntax, die in Blazor für Web- und Hybridanwendungen zum Einsatz kommt, nun auch für HTML-Rendering für E-Mails im HTML-Format oder andere HTML-Einsatzgebiete zur Verfügung.

Dazu gibt es in .NET 8.0 die neue Klasse Microsoft.AspNetCore.Components.Web.HtmlRenderer im NuGet-Paket Microsoft.AspNetCore.Components.Web.

Für das folgende Beispiel gibt es zunächst drei Razor-Komponenten. EMailTemplate.razor bindet Headline.razor und Footer.razor per Tags ein: <Headline> und <Footer>. Bei Headline wird ein Parameter übergeben. Bei Footer kann man ein Razor-Fragment übergeben.

Alle Styles sind im HTML-Dokument in <style>-Tags enthalten. Externe Style-Sheet-Dateien wie EMailTemplate.razor.css werden nicht wie Blazor automatisch integriert, sondern müssen explizit per <link rel="stylesheet" type="text/css" href="EMailTemplate.razor.css"> referenziert werden. Das funktioniert gut beim Rendering ins Dateisystem, ist aber nicht möglich bei E-Mails.

Der Code für EMailTemplate.razor sieht folgendermaßen aus:

<html>
<body>
 
 <style>
  body { font-family: Arial}
 </style>
 
 <Headline Text="Terminbestätigung"></Headline>
 
 <p>Guten Tag @Name,</p>
 <p>.NET 8.0 ist am <b>@Datum.ToLongDateString()</b> erschienen.</p>
 
 @{
   var url = "https://www.IT-Visions.de";
  }
 
 @* Einbinden einer weiteren Razor-Komponente mit Child Content *@
 <Footer>
  <p>
   Ihr Team von<br />
   <a href="@url">www.IT-Visions.de</a></p>
 </Footer>
 
</body>
</html>
 
@code {
 [Parameter]
 public string Name { get; set; }
 [Parameter]
 public DateTime Datum { get; set; } = new(2023, 11, 14);
}

Dies ist der Code für Headline.razor:

@* Razor Component mit einfachem Parameter *@
 
<style>
 .headline {
  color: white;
  background-color: #12B4FF;
  padding: 10px;
 }
</style>
 
<h3 class="headline">@Text</h3>
 
@code {
 [Parameter]
 public string Text { get; set; }
}

Und im Folgenden ist der Code für Footer.razor zu sehen:

@* Razor Component mit Template *@
 
<p>Mit freundlichen Grüßen</p>
@ChildContent
 
@code 
{
 [Parameter]
 public RenderFragment ChildContent { get; set; }
}
Online-Konferenz zu .NET 9.0 am 19. November

(Bild: Dmytro Vikarchuk/Shutterstock)

In der Online-Konferenz betterCode() .NET 9.0 am 19. November 2024 von iX und dpunkt.verlag werden .NET-Experten von www.IT-Visions.de den fertigen Stand von .NET 9.0 anhand von Praxisbeispielen präsentieren. Dazu zählen die Neuerungen bezüglich des .NET 9.0 SDK, C# 13.0, ASP.NET Core 9.0, Blazor 9.0, OR-Mapping mit Entity Framework Core 9.0, Windows Forms 9.0, WPF 9.0, WinUI, Cross-Plattform-Entwicklung mit .NET MAUI 9.0 und ein Ausblick auf .NET 10.0.

Der Ticketverkauf ist bereits gestartet: Vor Bekanntgabe des Programms sind vergünstigte Blind-Bird-Tickets erhältlich.

Der Code im folgenden Listing rendert in einer Konsolenanwendung die E-Mail. Das entstandene HTML-Dokument gibt er auf der Konsole aus, speichert ihn in einer Datei und verwendet ihn zum Versand einer E-Mail:

using System.Diagnostics;
using ITVisions;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
 
namespace NET8_Console;
 
class FCL_RazorRendering
{
 public async Task Run()
 {
  CUI.H1(nameof(FCL_RazorRendering));
 
  #region Vorbereiten des Renderns mit Razor Templates
  IServiceCollection services = new ServiceCollection();
  services.AddLogging((loggingBuilder) => loggingBuilder
        .SetMinimumLevel(LogLevel.Trace)
        .AddConsole()
        );
 
  IServiceProvider serviceProvider = services.BuildServiceProvider();
  ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
  #endregion
 
  #region HTML Rendering using a Razor Component
  // Klasse HtmlRenderer neu in .NET 8.0
  await using var renderer = new HtmlRenderer(serviceProvider, loggerFactory);
 
  var html = await renderer.Dispatcher.InvokeAsync(async () =>
  {
   // Parameter zusammenstellen
   var name = "Dr. Holger Schwichtenberg";
   CUI.Print("Parameter 'Name' = " + name);
   var pdic = new Dictionary<string, object>() { { "Name", name } };
   var pv = ParameterView.FromDictionary(pdic); // oder: var pv = ParameterView.Empty;
 
   // Nun EMailTemplate.razor rendern
   var output = await renderer.RenderComponentAsync<Razor_EMailTemplates.EMailTemplate>(pv);
   return output.ToHtmlString();
  });
  #endregion
 
  #region HTML anzeigen
  CUI.H2("Gerendertes HTML");
  CUI.PrintYellow(html);
  #endregion
 
  #region HTML speichern
  var path = Path.GetTempFileName();
  path = Path.ChangeExtension(path, ".html");
  System.IO.File.AppendAllText(path, html);
  // Start new Process to open the File in the default Browser
  Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
  #endregion
 
  #region HTML-E-Mail senden
  new ITVisions.Network.MailUtil().SendMail("absender@IT-Visions.de", 
                                            "empfänger@IT-Visions.de", 
                                            "Terminbestätigung .NET 8.0", 
                                            html, HTML: true);
  #endregion
 }
}

So schaut das gerendete HTML aus.

(Bild: Screenshot (Holger Schwichtenberg))

(rme)