it-swarm.com.de

Kann ich HTML/E-Mail-Vorlagen mit ASP.NET einrichten?

Ich arbeite an einer Website, auf der eine beträchtliche Anzahl von E-Mails verschickt wird. Ich möchte sowohl Kopf- als auch Fußzeilentext oder sogar Vorlagen einrichten, damit die Benutzer diese E-Mails bei Bedarf problemlos bearbeiten können.

Wenn ich den HTML-Code in C # -Speicherliterale einbetten, ist das hässlich und sie müssen sich um das Fluchen kümmern. Das Einfügen von flachen Dateien für die Kopf- und Fußzeile funktioniert möglicherweise, aber etwas fühlt sich einfach nicht richtig an.

Was wäre ideal, um eine .ASPX-Seite irgendwie als Vorlage zu verwenden, dann sagen Sie meinem Code einfach, dass er diese Seite liefern soll, und verwenden Sie den für die E-Mail zurückgegebenen HTML-Code.

Gibt es eine schöne und einfache Möglichkeit, dies zu tun? Gibt es einen besseren Weg, um dieses Problem zu lösen?

Aktualisierte:
Ich habe eine Antwort hinzugefügt, mit der Sie eine Standard-ASPX-Seite als E-Mail-Vorlage verwenden können. Ersetzen Sie einfach alle Variablen wie gewohnt, verwenden Sie Datenbindung usw. Erfassen Sie einfach die Ausgabe der Seite und voila! Sie haben Ihre HTML-E-Mail!

AKTUALISIERT MIT CAVEAT !!!:
Ich habe die MailDefinition-Klasse auf einigen aspx-Seiten verwendet, aber als ich versuchte, diese Klasse während eines laufenden Serverprozesses zu verwenden, schlug sie fehl. Ich glaube, es lag daran, dass die MailDefinition.CreateMailMessage () -Methode ein gültiges Steuerelement zum Verweisen erfordert, auch wenn sie nicht immer etwas tut. Aus diesem Grund würde ich meinen Ansatz mit einer Aspx-Seite oder Muns Ansatz mit einer Ascx-Seite empfehlen, was ein wenig besser erscheint.

93
John Bubriski

Hier gibt es schon eine Menge Antworten, aber ich bin auf einen großartigen Artikel zur Verwendung von Razor mit E-Mail-Templating gestoßen. Razor wurde mit ASP.NET MVC 3 gepusht, aber MVC muss nicht Razor verwenden. Dies ist eine ziemlich einfache Verarbeitung von E-Mail-Vorlagen

Der Artikel stellt fest: "Das Beste an Razor ist, dass es im Gegensatz zu seinem Vorgänger (Webforms) nicht an die Webumgebung gebunden ist. Wir können es leicht außerhalb des Webs hosten und als Template Engine für verschiedene Zwecke verwenden."

HTML-E-Mails mit RazorEngine erstellen - Teil 01 - Einführung

Verwenden von Razor-Vorlagen außerhalb von ASP.NET: Sie sind nicht mehr nur für HTML-Versionen gedacht!

Intelligentere E-Mail-Vorlagen in ASP.NET mit RazorEngine

Ähnliche Stackoverflow-QA

Templating mit neuer RazorEngine-API

Verwenden von Rasierer ohne MVC

Kann Razor View Engine auch außerhalb von asp.net verwendet werden }

70

Sie können auch versuchen, ein Steuerelement zu laden und es in eine Zeichenfolge zu rendern und als HTML-Body festzulegen:

// Declare stringbuilder to render control to
StringBuilder sb = new StringBuilder();

// Load the control
UserControl ctrl = (UserControl) LoadControl("~/Controls/UserControl.ascx");

// Do stuff with ctrl here

// Render the control into the stringbuilder
StringWriter sw = new StringWriter(sb);
Html32TextWriter htw = new Html32TextWriter(sw);
ctrl.RenderControl(htw);

// Get full body text
string body = sb.ToString();

Sie können dann Ihre E-Mail wie gewohnt erstellen:

MailMessage message = new MailMessage();
message.From = new MailAddress("[email protected]", "from name");
message.Subject = "Email Subject";
message.Body = body;
message.BodyEncoding = Encoding.ASCII;
message.IsBodyHtml = true;

SmtpClient smtp = new SmtpClient("server");
smtp.Send(message);

Ihr Benutzersteuerelement könnte andere Steuerelemente enthalten, z. B. eine Kopf- und Fußzeile, und auch Funktionen wie die Datenbindung nutzen.

55
Mun
35
John Sheehan

Wenn Sie Parameter wie Benutzernamen, Produktnamen usw. übergeben möchten, können Sie die Open-Source-Vorlagen-Engine NVelocity verwenden, um Ihre endgültigen E-Mails/HTML-Codes zu erstellen.

Ein Beispiel für eine NVelocity-Vorlage (MailTemplate.vm): 

A sample email template by <b>$name</b>.
<br />

Foreach example :
<br />    
#foreach ($item in $itemList)

[Date: $item.Date] Name: $item.Name, Value: $itemValue.Value
<br /><br />

#end

Generieren von Mail-Body durch MailTemplate.vm in Ihrer Anwendung: 

VelocityContext context = new VelocityContext();
context.Put("name", "ScarletGarden");
context.Put("itemList", itemList);

StringWriter writer = new StringWriter();

Velocity.MergeTemplate("MailTemplate.vm", context, writer);

string mailBody = writer.GetStringBuilder().ToString();

Der Ergebnis-Mail-Body lautet:

Eine Beispiel-E-Mail-Vorlage von ScarletGarden.

Für jedes Beispiel:

[Datum: 12.02.2009] Name: Nr. 1, Wert: 09

[Datum: 21.02.2009] Name: Punkt 4, Wert: 52

[Datum: 01.03.2009] Name: Nr. 2, Wert: 21

[Datum: 23.03.2009] Name: Nr. 6, Wert: 24

Zum Bearbeiten der Vorlagen können Sie möglicherweise FCKEditor verwenden und Ihre Vorlagen in Dateien speichern.

18
Canavar

Mail.dll E-Mail-Komponente enthält E-Mail-Vorlagen-Engine:

Hier ist die Syntaxübersicht:

<html>
<body>
Hi {FirstName} {LastName},

Here are your orders: 
{foreach Orders}
    Order '{Name}' sent to <strong>{Street}</strong>. 
{end}

</body>
</html>

Und der Code, der die Vorlage lädt, füllt Daten aus dem Objekt c # und sendet eine E-Mail:

Mail.Html(Template
              .FromFile("template.txt")
              .DataFrom(_contact)
              .Render())
    .Text("This is text version of the message.")
    .From(new MailBox("[email protected]", "Alice"))
    .To(new MailBox("[email protected]", "Bob"))
    .Subject("Your order")
    .UsingNewSmtp()
    .WithCredentials("[email protected]", "password")
    .Server("mail.com")
    .WithSSL()
    .Send();

Weitere Informationen erhalten Sie unter email template engine blog post.

Oder laden Sie einfach die E-Mail-Komponente Mail.dll herunter und probieren Sie es aus.

Bitte beachten Sie, dass dies ein kommerzielles Produkt ist, das ich erstellt habe.

7

Wenn Flexibilität eine Ihrer Voraussetzungen ist, könnte XSLT eine gute Wahl sein, die vollständig von .NET Framework unterstützt wird. Sie könnten sogar den Benutzer diese Dateien bearbeiten lassen. Dieser Artikel ( http://www.aspfree.com/c/a/XML/XSL-Transformations-using-ASP-NET/ ) kann für einen Start nützlich sein (msdn enthält weitere Informationen dazu). Wie von ScarletGarden gesagt, ist NVelocity eine weitere gute Wahl, aber ich bevorzuge XSLT wegen seiner "eingebauten" .NET-Framework-Unterstützung und Plattform-Agnostik.

6
Everton

Hier ist eine weitere Alternative, die XSL-Transformationen für komplexere E-Mail-Vorlagen verwendet: Senden von HTML-basierten E-Mails aus .NET-Anwendungen .

4
Alek Davis

Ich denke, du könntest auch so etwas tun:

Erstellen Sie eine .aspx-Seite, und fügen Sie diese am Ende der OnLoad-Methode ein, oder rufen Sie sie manuell auf.

    StringBuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    HtmlTextWriter htmlTW = new HtmlTextWriter(sw);
    this.Render(htmlTW);

Ich bin nicht sicher, ob es Probleme gibt, aber es sieht so aus, als würde es funktionieren. Auf diese Weise könnten Sie eine voll funktionsfähige ASPX-Seite anstelle der MailDefinition-Klasse verwenden, die nur Textersetzungen unterstützt.

4
John Bubriski

Sicher können Sie eine HTML-Vorlage erstellen und ich würde auch eine Textvorlage empfehlen. In der Vorlage können Sie einfach [KÖRPER] an der Stelle einfügen, an der der Körper platziert werden soll. Dann können Sie einfach die Vorlage lesen und den Körper durch den neuen Inhalt ersetzen. Sie können die E-Mail mit der .Nets Mail-Klasse senden. Sie müssen nur das Senden der E-Mail an alle Empfänger durchlaufen, nachdem Sie die E-Mail ursprünglich erstellt haben. Arbeitete wie ein Zauber für mich.

using System.Net.Mail;

// Email content
string HTMLTemplatePath = @"path";
string TextTemplatePath = @"path";
string HTMLBody = "";
string TextBody = "";

HTMLBody = File.ReadAllText(HTMLTemplatePath);
TextBody = File.ReadAllText(TextTemplatePath);

HTMLBody = HTMLBody.Replace(["[BODY]", content);
TextBody = HTMLBody.Replace(["[BODY]", content);

// Create email code
MailMessage m = new MailMessage();

m.From = new MailAddress("[email protected]", "display name");
m.To.Add("[email protected]");
m.Subject = "subject";

AlternateView plain = AlternateView.CreateAlternateViewFromString(_EmailBody + text, new System.Net.Mime.ContentType("text/plain"));
AlternateView html = AlternateView.CreateAlternateViewFromString(_EmailBody + body, new System.Net.Mime.ContentType("text/html"));
mail.AlternateViews.Add(plain);
mail.AlternateViews.Add(html);

SmtpClient smtp = new SmtpClient("server");
smtp.Send(m);
4
Josh Mein

Seien Sie vorsichtig, da SPAM-Filter anscheinend ASP.net-generierte HTML-Dateien blockieren, offensichtlich aufgrund von ViewState. Wenn Sie dies tun, stellen Sie sicher, dass die erzeugte HTML-Datei sauber ist.

Ich persönlich würde mit Asp.net MVC nachsehen, um Ihre gewünschten Ergebnisse zu erzielen. oder NVelocity ist ziemlich gut darin

2
danswain

ich hatte eine ähnliche Anforderung an eines der Projekte, bei denen Sie täglich eine große Anzahl von E-Mails senden mussten, und der Kunde wollte vollständige Kontrolle über HTML-Vorlagen für verschiedene Arten von E-Mails.

aufgrund der großen Anzahl von zu versendenden E-Mails war die Leistung ein Hauptanliegen.

was uns dabei einfiel, war ein statischer Inhalt in SQL Server, wo Sie die gesamte HTML-Template-Markierung (zusammen mit Platzhaltern wie [UserFirstName], [UserLastName], die zur Laufzeit durch echte Daten ersetzt werden) für verschiedene Arten von E-Mails speichern

dann haben wir diese Daten in den asp.net-Cache geladen - also lesen wir die HTML-Templates nicht immer und immer wieder - aber nur, wenn sie tatsächlich geändert werden

wir haben dem Kunden einen WYSIWYG-Editor zur Bearbeitung dieser Vorlagen über ein Admin-Webformular zur Verfügung gestellt. Bei Aktualisierungen setzen wir den asp.net-Cache zurück.

und dann hatten wir eine separate Tabelle für E-Mail-Protokolle - wo jede zu sendende E-Mail protokolliert wurde. Diese Tabelle enthielt Felder mit den Namen emailType, emailSent und numberOfTries. 

wir haben einfach alle 5 Minuten einen Job für wichtige E-Mail-Typen (wie Anmeldung eines neuen Mitglieds, Passwort vergessen) ausgeführt, die schnellstmöglich gesendet werden müssen

wir haben alle 15 Minuten einen neuen Job für weniger wichtige E-Mail-Typen (Werbe-E-Mail, E-Mail-Nachrichten usw.) ausgeführt.

auf diese Weise blockieren Sie nicht, dass Ihr Server unendliche E-Mails sendet, und Sie verarbeiten E-Mails im Stapel. Sobald eine E-Mail gesendet wurde, setzen Sie das E-Mail-Versandfeld auf 1.

1
Raj

Was wäre ideal, um eine .ASPX-Seite irgendwie als Vorlage zu verwenden, dann sagen Sie einfach meinem Code, dass er diese Seite bereitstellen soll, und verwenden Sie den für die E-Mail zurückgegebenen HTML-Code.

Sie können ganz einfach ein WebRequest erstellen, um eine ASPX-Seite aufzurufen und das resultierende HTML zu erhalten. Mit etwas mehr Arbeit können Sie es wahrscheinlich auch ohne WebRequest erledigen. Ein PageParser und ein Response.Filter würden es Ihnen ermöglichen, die Seite auszuführen und die Ausgabe zu erfassen ... obwohl es einige elegantere Möglichkeiten gibt.

1
Mark Brackett

Schauen Sie sich SubSonic (www.subsonicproject.com) an. Sie machen genau das, um Code zu generieren - die Vorlage ist Standard-ASPX und gibt c # aus. Die gleiche Methode kann für Ihr Szenario wiederverwendet werden.

1
jvenema

Beachten Sie, dass für die aspx- und ascx-Lösungen ein aktueller HttpContext erforderlich ist und daher nicht asynchron (z. B. in Threads) ohne viel Arbeit verwendet werden kann.

1
Rosco

Ich denke, die einfache Antwort ist MvcMailer. Es ist das NuGet-Paket, mit dem Sie Ihre bevorzugte Ansichts-Engine zum Generieren von E-Mails verwenden können. Siehe das NuGet-Paket hier und die Projektdokumentation

Ich hoffe es hilft!

1
Sohan

DotLiquid ist eine weitere Option. Sie geben Werte aus einem Klassenmodell als {{ user.name }} an, und zur Laufzeit geben Sie die Daten in dieser Klasse und die Vorlage mit dem Markup an, und die Werte werden für Sie zusammengeführt. Es ähnelt in vielerlei Hinsicht der Verwendung der Razor-Templating-Engine. Es unterstützt komplexere Dinge wie Loops und verschiedene Funktionen wie ToUpper. Das Schöne daran ist, dass diese "sicher" sind, so dass Benutzer, die die Vorlagen erstellen, Ihr System nicht abstürzen oder unsicheren Code schreiben können, wie Sie es in einem Rasiermesser tun würden: http://dotliquidmarkup.org/try-online

1
AaronLS

Wenn Sie dem ASPNET und den zugehörigen Benutzern die Berechtigung zum Lesen und Schreiben einer Datei erteilen können, können Sie dazu ganz einfach eine HTML-Datei mit den String.Format()-Platzhaltern ({0}, {1:C} usw.) verwenden. 

Lesen Sie die Datei lediglich als Zeichenfolge mit Klassen aus dem System.IO-Namespace ein. Wenn Sie diese Zeichenfolge haben, übergeben Sie sie als erstes Argument an String.Format() und geben Sie die Parameter an.

Behalten Sie diese Zeichenfolge bei sich und verwenden Sie sie als Hauptteil der E-Mail, und Sie sind im Wesentlichen fertig. Wir machen das heute auf Dutzenden von (zugegebenermaßen kleinen) Websites und hatten keinerlei Probleme.

Ich sollte beachten, dass dies am besten funktioniert, wenn (a) Sie nicht zig Millionen E-Mails gleichzeitig senden, (b) Sie nicht jede E-Mail personalisieren (andernfalls fressen Sie eine Menge Zeichenketten) und (c ) Die HTML-Datei selbst ist relativ klein.

0
John Rudy

Ich würde eine Vorlagenbibliothek wie TemplateMachine verwenden. Auf diese Weise können Sie Ihre E-Mail-Vorlage meistens mit normalem Text zusammenstellen und dann mithilfe von Regeln nach Bedarf Werte einfügen/ersetzen. Sehr ähnlich zu ERB in Ruby. Auf diese Weise können Sie die Erzeugung des E-Mail-Inhalts trennen, ohne Sie an ASPX usw. zu sehr zu binden. Sobald der Inhalt damit erstellt wurde, können Sie eine E-Mail versenden. 

0
MikeJ

Ähnlich wie Canavars Antwort, aber anstelle von NVelocity verwende ich immer " StringTemplate " Ich lade die Vorlage aus einer Konfigurationsdatei oder lade eine externe Datei mit File.ReadAllText () und setze die Werte.

Es ist ein Java-Projekt, aber der C # -Port ist solide und ich habe es in mehreren Projekten verwendet (es wurde nur für E-Mail-Templates mit der Vorlage in einer externen Datei verwendet).

Alternativen sind immer gut.

0

Ich mag Rajs Antwort. Programme wie ListManager und Frameworks wie DNN haben ähnliche Aufgaben. Wenn WYSIWYG-Editoren das Editieren von in SQL gespeichertem HTML-Code erfordern, ist eine einfache und unkomplizierte Methode, mit der Editierkopfzeilen problemlos von Fußzeilen aus angepasst werden können. usw. sowie die Verwendung von Token zum dynamischen Einfügen von Werten. 

Wenn Sie die obige Methode (oder eine wirklich, wirklich) verwenden, sollten Sie sich genau überlegen, welche Arten von Stilen und Tags von den Editoren eingefügt werden dürfen. Wenn Sie denken, Browser seien pingelig, warten Sie einfach, bis Sie sehen, wie unterschiedlich E-Mail-Clients dasselbe darstellen.

0
Nick

Wirf einfach die Bibliothek, die ich benutze, in den Mix: https://github.com/lukencode/FluentEmail

Es rendert E-Mails mit RazorLight , verwendet den fließenden Stil zum Erstellen von E-Mails und unterstützt mehrere sofort einsatzbereite Absender. Es enthält auch Erweiterungsmethoden für ASP.NET DI. Einfach zu bedienen, wenig Setup, mit Nur-Text- und HTML-Unterstützung.

0
ahong

@bardev bietet eine gute Lösung, ist aber leider nicht in allen Fällen ideal. Meiner war einer von ihnen.

Ich verwende WebForms in einer Website (ich schwöre, ich werde nie wieder eine Website verwenden - was für ein PITA) in VS 2013.

Ich habe den Razor-Vorschlag ausprobiert, aber als meine Website habe ich nicht den wichtigen IntelliSense erhalten, den die IDE in einem MVC-Projekt liefert. Ich benutze den Designer auch gerne für meine Vorlagen - ein perfekter Ort für ein UserControl.

Nix wieder bei Razor.

Also habe ich mir dieses kleine Framework ausgedacht (Hat Tipps an @mun für UserControl und @imatoria für Strong Typing). Der einzige potenzielle Problempunkt, den ich sehen kann, ist, dass Sie darauf achten müssen, dass Ihr .ASCX-Dateiname mit dem Klassennamen synchron ist. Wenn Sie sich verirren, erhalten Sie einen Laufzeitfehler.

FWIW: In meinem Test mag der RenderControl () -Aufruf ein Page-Control nicht, daher bin ich mit UserControl gegangen.

Ich bin mir ziemlich sicher, dass ich hier alles aufgenommen habe. Lass mich wissen, wenn ich etwas ausgelassen habe.

HTH

Verwendungszweck:

Partial Class Purchase
  Inherits UserControl

  Private Sub SendReceipt()
    Dim oTemplate As MailTemplates.PurchaseReceipt

    oTemplate = MailTemplates.Templates.PurchaseReceipt(Me)
    oTemplate.Name = "James Bond"
    oTemplate.OrderTotal = 3500000
    oTemplate.OrderDescription = "Q-Stuff"
    oTemplate.InjectCss("PurchaseReceipt")

    Utils.SendMail("{0} <[email protected]>".ToFormat(oTemplate.Name), "Purchase Receipt", oTemplate.ToHtml)
  End Sub
End Class

Basisklasse:

Namespace MailTemplates
  Public MustInherit Class BaseTemplate
    Inherits UserControl

    Public Shared Function GetTemplate(Caller As TemplateControl, Template As Type) As BaseTemplate
      Return Caller.LoadControl("~/MailTemplates/{0}.ascx".ToFormat(Template.Name))
    End Function



    Public Sub InjectCss(FileName As String)
      If Me.Styler IsNot Nothing Then
        Me.Styler.Controls.Add(New Controls.Styler(FileName))
      End If
    End Sub



    Private ReadOnly Property Styler As PlaceHolder
      Get
        If _Styler Is Nothing Then
          _Styler = Me.FindNestedControl(GetType(PlaceHolder))
        End If

        Return _Styler
      End Get
    End Property
    Private _Styler As PlaceHolder
  End Class
End Namespace

"Factory" Klasse:

Namespace MailTemplates
  Public Class Templates
    Public Shared ReadOnly Property PurchaseReceipt(Caller As TemplateControl) As PurchaseReceipt
      Get
        Return BaseTemplate.GetTemplate(Caller, GetType(PurchaseReceipt))
      End Get
    End Property
  End Class
End Namespace

Vorlagenklasse:

Namespace MailTemplates
  Public MustInherit Class PurchaseReceipt
    Inherits BaseTemplate

    Public MustOverride WriteOnly Property Name As String
    Public MustOverride WriteOnly Property OrderTotal As Decimal
    Public MustOverride WriteOnly Property OrderDescription As String
  End Class
End Namespace

ASCX-Header:

<%@ Control Language="VB" ClassName="_Header" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<!--
  See https://www.campaignmonitor.com/blog/post/3317/ for discussion of DocType in HTML Email
-->

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title></title>
  <asp:PlaceHolder ID="plcStyler" runat="server"></asp:PlaceHolder>
</head>
<body>

ASCX-Fußzeile:

<%@ Control Language="VB" ClassName="_Footer" %>

</body>
</html>

ASCX-Vorlage:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="PurchaseReceipt.ascx.vb" Inherits="PurchaseReceipt" %>

<%@ Register Src="_Header.ascx" TagName="Header" TagPrefix="uc" %>
<%@ Register Src="_Footer.ascx" TagName="Footer" TagPrefix="uc" %>

<uc:Header ID="ctlHeader" runat="server" />

  <p>Name: <asp:Label ID="lblName" runat="server"></asp:Label></p>
  <p>Order Total: <asp:Label ID="lblOrderTotal" runat="server"></asp:Label></p>
  <p>Order Description: <asp:Label ID="lblOrderDescription" runat="server"></asp:Label></p>

<uc:Footer ID="ctlFooter" runat="server" />

ASCX-Vorlagencodedatei:

Partial Class PurchaseReceipt
  Inherits MailTemplates.PurchaseReceipt

  Public Overrides WriteOnly Property Name As String
    Set(Value As String)
      lblName.Text = Value
    End Set
  End Property



  Public Overrides WriteOnly Property OrderTotal As Decimal
    Set(Value As Boolean)
      lblOrderTotal.Text = Value
    End Set
  End Property



  Public Overrides WriteOnly Property OrderDescription As Decimal
    Set(Value As Boolean)
      lblOrderDescription.Text = Value
    End Set
  End Property
End Class

Helfer:

'
' FindNestedControl helpers based on tip by @andleer
' at http://stackoverflow.com/questions/619449/
'

Public Module Helpers
  <Extension>
  Public Function AllControls(Control As Control) As List(Of Control)
    Return Control.Controls.Flatten
  End Function



  <Extension>
  Public Function FindNestedControl(Control As Control, Id As String) As Control
    Return Control.Controls.Flatten(Function(C) C.ID = Id).SingleOrDefault
  End Function



  <Extension>
  Public Function FindNestedControl(Control As Control, Type As Type) As Control
    Return Control.Controls.Flatten(Function(C) C.GetType = Type).SingleOrDefault
  End Function



  <Extension>
  Public Function Flatten(Controls As ControlCollection) As List(Of Control)
    Flatten = New List(Of Control)

    Controls.Traverse(Sub(Control) Flatten.Add(Control))
  End Function


  <Extension>
  Public Function Flatten(Controls As ControlCollection, Predicate As Func(Of Control, Boolean)) As List(Of Control)
    Flatten = New List(Of Control)

    Controls.Traverse(Sub(Control)
                        If Predicate(Control) Then
                          Flatten.Add(Control)
                        End If
                      End Sub)
  End Function



  <Extension>
  Public Sub Traverse(Controls As ControlCollection, Action As Action(Of Control))
    Controls.Cast(Of Control).ToList.ForEach(Sub(Control As Control)
                                               Action(Control)

                                               If Control.HasControls Then
                                                 Control.Controls.Traverse(Action)
                                               End If
                                             End Sub)
  End Sub



  <Extension()>
  Public Function ToFormat(Template As String, ParamArray Values As Object()) As String
    Return String.Format(Template, Values)
  End Function



  <Extension()>
  Public Function ToHtml(Control As Control) As String
    Dim oSb As StringBuilder

    oSb = New StringBuilder

    Using oSw As New StringWriter(oSb)
      Using oTw As New HtmlTextWriter(oSw)
        Control.RenderControl(oTw)
        Return oSb.ToString
      End Using
    End Using
  End Function
End Module



Namespace Controls
  Public Class Styler
    Inherits LiteralControl

    Public Sub New(FileName As String)
      Dim _
        sFileName,
        sFilePath As String

      sFileName = Path.GetFileNameWithoutExtension(FileName)
      sFilePath = HttpContext.Current.Server.MapPath("~/Styles/{0}.css".ToFormat(sFileName))

      If File.Exists(sFilePath) Then
        Me.Text = "{0}<style type=""text/css"">{0}{1}</style>{0}".ToFormat(vbCrLf, File.ReadAllText(sFilePath))
      Else
        Me.Text = String.Empty
      End If
    End Sub
  End Class
End Namespace



Public Class Utils
  Public Shared Sub SendMail(Recipient As MailAddress, Subject As String, HtmlBody As String)
    Using oMessage As New MailMessage
      oMessage.To.Add(Recipient)
      oMessage.IsBodyHtml = True
      oMessage.Subject = Subject.Trim
      oMessage.Body = HtmlBody.Trim

      Using oClient As New SmtpClient
        oClient.Send(oMessage)
      End Using
    End Using
  End Sub
End Class
0
InteXX

Legen Sie die Menge der E-Mail-Nachricht IsBodyHtml = true fest

Nehmen Sie Ihr Objekt mit Ihrem E-Mail-Inhalt. Serialisieren Sie das Objekt Und verwenden Sie xml/xslt, um den HTML-Inhalt zu generieren. 

Wenn Sie möchten, dass AlternateViews dasselbe tun, verwenden Sie nur eine andere Xslt-Vorlage zum Erstellen des Nur-Text-Inhalts.

einer der wichtigsten Vorteile dabei ist, wenn Sie Ihr Layout ändern möchten, müssen Sie lediglich die xslt-Vorlage aktualisieren.

0
Bob The Janitor

Mit der Klasse WebClient können Sie auf einfache Weise vorgehen:

public static string GetHTMLBody(string url)
{
    string htmlBody;

    using (WebClient client = new WebClient ())
    {
        htmlBody = client.DownloadString(url);
    }

    return htmlBody;
}

Dann nennen Sie es einfach so:

string url = "http://www.yourwebsite.com";
message.Body = GetHTMLBody(url);

Natürlich muss Ihr CSS eingebettet sein, um die Stile der Webseite in den meisten E-Mail-Clients (wie z. B. Outlook) anzuzeigen. Wenn Ihre E-Mail dynamischen Inhalt enthält (z. B. Kundenname), würde ich empfehlen, QueryStrings auf Ihrer Website zu verwenden, um die Daten aufzufüllen. (ex. http://www.yourwebsite.com?CustomerName=Bob )

0
ROFLwTIME