web-dev-qa-db-fra.com

Puis-je configurer des modèles HTML/Email avec ASP.NET?

Je travaille sur un site qui enverra un nombre important de courriels. Je souhaite configurer le texte de l'en-tête et du pied de page, voire même des modèles, pour permettre aux utilisateurs de modifier facilement ces courriels s'ils le souhaitent.

Si j'intègre le code HTML dans les littéraux de chaîne C #, c'est moche et ils devront s'inquiéter de s'échapper. L'inclusion de fichiers plats pour l'en-tête et le pied de page peut fonctionner, mais quelque chose ne va pas.

Quel serait l'idéal d'utiliser une page .ASPX comme modèle, puis de demander à mon code de servir cette page et d'utiliser le code HTML renvoyé pour le courrier électronique.

Y a-t-il un moyen simple et agréable de le faire? Y a-t-il une meilleure façon de résoudre ce problème?

Mis à jour:
J'ai ajouté une réponse qui vous permet d'utiliser une page standard .aspx comme modèle de courrier électronique. Il suffit de remplacer toutes les variables comme vous le feriez normalement, d'utiliser la liaison de données, etc. Ensuite, capturez simplement le résultat de la page et le tour est joué! Vous avez votre email HTML!

MISE À JOUR AVEC CAVEAT !!!:
J'utilisais très bien la classe MailDefinition sur certaines pages aspx, mais en essayant d'utiliser cette classe au cours d'un processus serveur en cours d'exécution, elle a échoué. Je pense que c’est parce que la méthode MailDefinition.CreateMailMessage () nécessite un contrôle valide pour faire référence, même si elle ne fait pas toujours quelque chose. Pour cette raison, je recommanderais mon approche en utilisant une page aspx ou celle de Mun en utilisant une page ascx, ce qui semble un peu mieux.

93
John Bubriski

Il y a déjà une tonne de réponses ici, mais je suis tombé sur un excellent article sur l'utilisation de Razor avec un modèle de courrier électronique. Razor a été poussé avec ASP.NET MVC 3, mais MVC n’est pas obligé d’utiliser Razor. Ceci est un traitement assez astucieux de faire des modèles de courrier électronique

Comme le précise l'article, "la meilleure chose à propos de Razor est que, contrairement à son prédécesseur (formulaires Web), il n'est pas lié à l'environnement Web, nous pouvons facilement l'héberger en dehors du Web et l'utiliser comme moteur de modèle à des fins diverses."

Générer des emails HTML avec RazorEngine - Partie 01 - Introduction

Tirer parti des modèles de rasoir en dehors d’ASP.NET: ils ne sont pas uniquement destinés à HTML!

Des modèles de messagerie plus intelligents sous ASP.NET avec RazorEngine

QA Stackoverflow similaire

Templating utilisant la nouvelle API RazorEngine

Utilisation de Razor sans MVC

Est-il possible d'utiliser Razor View Engine en dehors de asp.net

70
Mike Barlow - BarDev

Vous pouvez également essayer de charger un contrôle, puis de le convertir en chaîne et de le définir en tant que corps HTML:

// 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();

Vous pouvez ensuite construire votre email comme d'habitude:

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);

Votre contrôle utilisateur peut contenir d'autres contrôles, tels qu'un en-tête et un pied de page, ainsi que des fonctionnalités telles que la liaison de données.

55
Mun

Vous pouvez essayer la classe MailDefinition

35
John Sheehan

Si vous souhaitez transmettre des paramètres tels que les noms d'utilisateur, les noms de produit, etc., vous pouvez utiliser le moteur de modèle open source NVelocity pour produire votre courrier électronique/HTML final.

Un exemple de modèle NVelocity (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

Génération de corps de courrier par MailTemplate.vm dans votre application: 

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();

Le corps du courrier résultant est:

Un exemple de modèle de courrier électronique par ScarletGarden.

Par exemple:

[Date: 12.02.2009] Nom: Poste 1, Valeur: 09

[Date: 21.02.2009] Nom: Poste 4, Valeur: 52

[Date: 01.03.2009] Nom: Poste 2, Valeur: 21

[Date: 23.03.2009] Nom: poste 6, Valeur: 24

Pour éditer les modèles, vous pouvez peut-être utiliser FCKEditor et enregistrer vos modèles dans des fichiers.

18
Canavar

Composant courrier électronique Mail.dll inclut le moteur de modèle de courrier électronique:

Voici la synthèse de la syntaxe:

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

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

</body>
</html>

Et le code qui charge le modèle, remplit les données de l’objet c # et envoie un courrier électronique:

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();

Vous pouvez obtenir plus d'informations sur moteur de modèle d'email blog post.

Ou tout simplement télécharger Composant de messagerie Mail.dll et l'essayer.

Veuillez noter qu'il s'agit d'un produit commercial que j'ai créé.

7

Si la flexibilité est l’un de vos prérequis, XSLT peut être un bon choix, qui est entièrement pris en charge par le framework .NET et vous pourrez même laisser l’utilisateur éditer ces fichiers. Cet article ( http://www.aspfree.com/c/a/XML/XSL-Transformations-using-ASP-NET/ ) pourrait être utile pour un début (msdn a plus d'informations à ce sujet). Comme indiqué par ScarletGarden, NVelocity est un autre bon choix, mais je préfère XSLT pour son support "intégré" .NET Framework et sa plate-forme agnostique.

6
Everton

Voici une autre alternative qui utilise les transformations XSL pour des modèles de courrier électronique plus complexes: Envoi de courrier électronique au format HTML à partir d'applications .NET .

4
Alek Davis

Je pense que vous pourriez aussi faire quelque chose comme ça:

Créez une page .aspx et mettez-la à la fin de la méthode OnLoad ou appelez-la manuellement.

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

Je ne suis pas sûr qu'il y ait des problèmes potentiels avec cela, mais il semble que cela fonctionnerait. De cette façon, vous pouvez utiliser une page .aspx complète au lieu de la classe MailDefinition qui prend uniquement en charge les remplacements de texte.

4
John Bubriski

Bien sûr, vous pouvez créer un modèle HTML et je vous recommanderais également un modèle de texte. Dans le modèle, vous pouvez simplement mettre [BODY] à la place du corps, puis vous pouvez simplement lire le modèle et remplacer le corps par le nouveau contenu. Vous pouvez envoyer le courrier électronique à l'aide de la classe de courrier .Nets. Il vous suffit de suivre l'envoi de l'e-mail à tous les destinataires après la création initiale de l'e-mail. A fonctionné à merveille pour moi.

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

Attention, les filtres anti-spam semblent bloquer le code HTML généré par ASP.net, apparemment à cause de ViewState. Par conséquent, si vous envisagez de le faire, assurez-vous que le code HTML généré est propre.

Personnellement, je voudrais envisager d'utiliser Asp.net MVC pour obtenir les résultats souhaités. ou NVelocity est assez bon à cela

2
danswain

j'avais une exigence similaire sur l'un des projets où vous deviez envoyer un nombre considérable de courriels chaque jour, et le client voulait un contrôle complet sur les modèles HTML pour différents types de courriels.

en raison du grand nombre de courriels à envoyer, les performances étaient une préoccupation majeure.

nous avons trouvé un contenu statique dans le serveur SQL où vous sauvegardiez le balisage complet du modèle html (avec des espaces réservés, tels que [UserFirstName], [UserLastName] qui sont remplacés par des données réelles au moment de l'exécution) pour différents types de courriels

puis nous avons chargé ces données dans le cache asp.net - nous ne lisons donc pas les modèles HTML encore et encore - mais seulement lorsqu'ils sont réellement modifiés

nous avons donné au client un éditeur WYSIWYG pour modifier ces modèles via un formulaire Web administrateur. chaque fois que des mises à jour ont été effectuées, nous réinitialisons le cache asp.net.

et puis nous avons eu une table séparée pour les journaux d'email - où chaque email à envoyer était enregistré. cette table avait des champs appelés emailType, emailSent et numberOfTries. 

nous avons simplement exécuté un travail toutes les 5 minutes pour les types d'e-mails importants (comme l'inscription de nouveaux membres, mot de passe oublié) qui doivent être envoyés dès que possible.

nous avons exécuté un autre travail toutes les 15 minutes pour les types de courrier électronique moins importants (tels que les courriels de promotion, les courriels d'actualité, etc.)

de cette façon, vous ne bloquez pas votre serveur en envoyant des emails non-stop et vous traitez les mails en batch. une fois le courrier électronique envoyé, définissez le champ emailSent sur 1.

1
Raj

Quel serait l'idéal d'utiliser une page .ASPX comme modèle, puis de demander à mon code de servir cette page et d'utiliser le code HTML renvoyé pour le courrier électronique.

Vous pouvez facilement créer un WebRequest pour atteindre une page ASPX et obtenir le code HTML résultant. Avec un peu plus de travail, vous pouvez probablement le faire sans WebRequest. Un PageParser et un Response.Filter vous permettraient d'exécuter la page et de capturer la sortie ... bien qu'il puisse exister des méthodes plus élégantes.

1
Mark Brackett

Regardez SubSonic (www.subsonicproject.com). C'est exactement ce qu'ils font pour générer du code - le modèle est un ASPX standard et génère le c #. La même méthode serait réutilisable pour votre scénario.

1
jvenema

Notez que les solutions aspx et ascx nécessitent un HttpContext actuel et ne peuvent donc pas être utilisées de manière asynchrone (par exemple, dans des threads) sans beaucoup de travail.

1
Rosco

Je pense que la réponse facile est MvcMailer. C’est le package NuGet qui vous permet d’utiliser votre moteur de visualisation favori pour générer des emails. Voir le package NuGet ici et la documentation du projet

J'espère que ça aide!

1
Sohan

DotLiquid est une autre option. Vous spécifiez les valeurs d'un modèle de classe sous la forme {{ user.name }}, puis au moment de l'exécution, vous fournissez les données de cette classe, ainsi que le modèle avec le balisage, qui fusionnera les valeurs pour vous. Cela ressemble à l'utilisation du moteur de gabarit Razor à bien des égards. Il supporte des choses plus complexes comme les boucles et diverses fonctions comme ToUpper. La bonne chose est que ceux-ci sont "sûrs" afin que l'utilisateur qui crée les modèles ne puisse pas planter votre système ni écrire du code non sécurisé comme vous le feriez dans rasoir: http://dotliquidmarkup.org/try-online

1
AaronLS

Si vous pouvez autoriser ASPNET et les utilisateurs associés à lire et à écrire un fichier, vous pouvez facilement utiliser un fichier HTML avec des espaces réservés standard String.Format() ({0}, {1:C}, etc.). 

Simplement lire dans le fichier, en tant que chaîne, en utilisant des classes de l'espace de noms System.IO. Une fois que vous avez cette chaîne, transmettez-la comme premier argument à String.Format() et fournissez les paramètres.

Conservez cette chaîne et utilisez-la comme corps du courrier électronique, et vous avez pratiquement terminé. Nous le faisons sur des dizaines de sites (certes de petite taille) aujourd'hui, et n'avons rencontré aucun problème.

Je devrais noter que cela fonctionne mieux si (a) vous n'envoyez pas plusieurs millions de courriers électroniques à la fois, (b) vous ne personnalisez pas chaque courrier électronique (sinon vous mangez une tonne de chaînes) ) le fichier HTML lui-même est relativement petit.

0
John Rudy

J'utiliserais une bibliothèque de modèles comme TemplateMachine . Cela vous permet généralement de mettre votre modèle de courrier électronique avec du texte normal, puis d'utiliser des règles pour injecter/remplacer des valeurs si nécessaire. Très similaire à ERB en Ruby. Cela vous permet de séparer la génération du contenu du courrier sans trop vous attacher à quelque chose comme ASPX, etc. Une fois le contenu généré avec cela, vous pouvez envoyer un courrier électronique. 

0
MikeJ

Semblable à la réponse de Canavar, mais au lieu de NVelocity, j’utilise toujours " StringTemplate " Je charge le modèle à partir d’un fichier de configuration ou un fichier externe à l’aide de File.ReadAllText (), puis je définis les valeurs.

C'est un projet Java mais le port C # est solide et je l'ai utilisé dans plusieurs projets (juste utilisé pour la création de modèles de courrier électronique en utilisant le modèle dans un fichier externe).

Les alternatives sont toujours bonnes.

0
Bryan Bailliache

J'aime la réponse de Raj. Des programmes tels que ListManager et des frameworks tels que DNN agissent de la même manière. Si un éditeur facile à modifier est requis, les éditeurs WYSIWYG permettant de modifier le code HTML stocké dans SQL constituent un moyen très simple et simple à utiliser. etc., ainsi que l’utilisation de jetons pour insérer dynamiquement des valeurs. 

Une chose à garder à l’esprit si vous utilisez la méthode ci-dessus (ou n’importe laquelle, en réalité) est d’être stricte et attentive quant aux types de style et de balises que vous autorisez les éditeurs à insérer. Si vous pensez que les navigateurs sont pointilleux, attendez de voir comment les clients de messagerie produisent différemment le même rendu ...

0
Nick

J'ajoute simplement la bibliothèque que j'utilise dans le mélange: https://github.com/lukencode/FluentEmail

Il rend les courriels en utilisant RazorLight , utilise un style fluide pour créer des courriels et prend en charge plusieurs expéditeurs prêts à l'emploi. Il vient avec des méthodes d'extension pour ASP.NET DI aussi. Simple à utiliser, peu d'installation, avec prise en charge du texte brut et HTML.

0
ahong

@bardev fournit une bonne solution, mais malheureusement ce n'est pas idéal dans tous les cas. Le mien était l'un d'entre eux.

J'utilise WebForms dans un site Web (je jure que je n'utiliserai plus jamais de site Web - quel PITA) dans VS 2013.

J'ai essayé la suggestion Razor, mais le mien étant un site Web, je n'ai pas compris le très important IntelliSense fourni par IDE dans un projet MVC. J'aime aussi utiliser le concepteur pour mes modèles - un endroit parfait pour un UserControl.

Nix sur Razor à nouveau.

J'ai donc créé ce petit framework (astuces à @mun pour UserControl et @imatoria pour Strong Typing). Le seul problème potentiel que je puisse voir est que vous devez veiller à maintenir votre nom de fichier .ASCX synchronisé avec son nom de classe. Si vous vous égarez, vous obtiendrez une erreur d'exécution.

FWIW: Lors de mes tests au moins, l'appel de RenderControl () n'aime pas un contrôle de page, alors je suis allé avec UserControl.

Je suis sûr que j'ai tout inclus ici; laissez-moi savoir si j'ai oublié quelque chose.

HTH

Usage:

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

Classe de base:

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

Classe "Usine":

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

Classe de modèle:

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

En-tête ASCX:

<%@ 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 Footer:

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

</body>
</html>

Modèle ASCX:

<%@ 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" />

Modèle de code ASCX:

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

Aides:

'
' 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

Définir la définition du message électronique IsBodyHtml = true

Prenez votre objet qui contient le contenu de votre email Sérialisez l'objet .__ et utilisez xml/xslt pour générer le contenu html. 

Si vous souhaitez effectuer AlternateViews, procédez de la même manière: jmein utilise uniquement un modèle xslt différent pour créer le contenu en texte brut.

l'un des principaux avantages est que si vous souhaitez modifier votre mise en page, il vous suffit de mettre à jour le modèle xslt.

0
Bob The Janitor

Voici un moyen simple d'utiliser la classe WebClient:

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

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

    return htmlBody;
}

Puis appelez ça comme ça:

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

Bien entendu, votre code CSS devra être aligné afin d’indiquer les styles de la page Web dans la plupart des clients de messagerie (tels que Outlook). Si votre courrier électronique affiche un contenu dynamique (par exemple, le nom du client), je vous recommanderais d'utiliser QueryStrings sur votre site Web pour renseigner les données. (ex. http://www.votre siteweb.com?nomClient=Bob )

0
ROFLwTIME