Создание HTML тела электронной почты в C#
есть ли лучший способ создать HTML-письмо в C# (для отправки через System.Net. Mail), чем использовать Stringbuilder для выполнения следующих действий:
string userName = "John Doe";
StringBuilder mailBody = new StringBuilder();
mailBody.AppendFormat("<h1>Heading Here</h1>");
mailBody.AppendFormat("Dear {0}," userName);
mailBody.AppendFormat("<br />");
mailBody.AppendFormat("<p>First part of the email body goes here</p>");
и так далее, и так далее?
10 ответов:
можно использовать класс MailDefinition.
вот как вы его используете:
MailDefinition md = new MailDefinition(); md.From = "[email protected]"; md.IsBodyHtml = true; md.Subject = "Test of MailDefinition"; ListDictionary replacements = new ListDictionary(); replacements.Add("{name}", "Martin"); replacements.Add("{country}", "Denmark"); string body = "<div>Hello {name} You're from {country}.</div>"; MailMessage msg = md.CreateMailMessage("[email protected]", replacements, body, new System.Web.UI.Control());кроме того, я написал в блоге о том, как создание HTML-тела электронной почты в C# с помощью шаблонов с помощью класса MailDefinition.
использовать систему.Сеть.ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.Класса HtmlTextWriter.
StringWriter writer = new StringWriter(); HtmlTextWriter html = new HtmlTextWriter(writer); html.RenderBeginTag(HtmlTextWriterTag.H1); html.WriteEncodedText("Heading Here"); html.RenderEndTag(); html.WriteEncodedText(String.Format("Dear {0}", userName)); html.WriteBreak(); html.RenderBeginTag(HtmlTextWriterTag.P); html.WriteEncodedText("First part of the email body goes here"); html.RenderEndTag(); html.Flush(); string htmlString = writer.ToString();для обширного HTML, который включает в себя создание атрибутов стиля HtmlTextWriter, вероятно, лучший способ пойти. Однако он может быть немного неуклюжим в использовании, и некоторые разработчики, такие как сама разметка, легко читаются, но извращенный выбор HtmlTextWriter в отношении отступа немного странный.
в этом примере вы также можете использовать XmlTextWriter довольно эффективно: -
writer = new StringWriter(); XmlTextWriter xml = new XmlTextWriter(writer); xml.Formatting = Formatting.Indented; xml.WriteElementString("h1", "Heading Here"); xml.WriteString(String.Format("Dear {0}", userName)); xml.WriteStartElement("br"); xml.WriteEndElement(); xml.WriteElementString("p", "First part of the email body goes here"); xml.Flush();
Обновил Ответ:
документация
SmtpClient, класс, используемый в этом ответе, теперь читает: 'устаревший ("SmtpClient и его сеть типов плохо спроектированы, мы настоятельно рекомендуем вам использовать https://github.com/jstedfast/MailKit и https://github.com/jstedfast/MimeKit вместо")'.источник:https://www.infoq.com/news/2017/04/MailKit-MimeKit-Official
Оригинал Ответ:
использование класса MailDefinition является неправильным подходом. Да, это удобно, но это также примитивно и зависит от элементов управления веб-интерфейсом-это не имеет смысла для чего-то, что обычно является задачей на стороне сервера.
подход, представленный ниже, основан на документации MSDN и сообщение Куреши на CodeProject.com.
Примечание: этот пример извлекает HTML-файл, изображения и вложения из встроенных ресурсов, но с использованием других Альтернативы для получения потоков для этих элементов хороши, например, жестко закодированные строки, локальные файлы и т. д.
Stream htmlStream = null; Stream imageStream = null; Stream fileStream = null; try { // Create the message. var from = new MailAddress(FROM_EMAIL, FROM_NAME); var to = new MailAddress(TO_EMAIL, TO_NAME); var msg = new MailMessage(from, to); msg.Subject = SUBJECT; msg.SubjectEncoding = Encoding.UTF8; // Get the HTML from an embedded resource. var assembly = Assembly.GetExecutingAssembly(); htmlStream = assembly.GetManifestResourceStream(HTML_RESOURCE_PATH); // Perform replacements on the HTML file (if you're using it as a template). var reader = new StreamReader(htmlStream); var body = reader .ReadToEnd() .Replace("%TEMPLATE_TOKEN1%", TOKEN1_VALUE) .Replace("%TEMPLATE_TOKEN2%", TOKEN2_VALUE); // and so on... // Create an alternate view and add it to the email. var altView = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html); msg.AlternateViews.Add(altView); // Get the image from an embedded resource. The <img> tag in the HTML is: // <img src="pid:IMAGE.PNG"> imageStream = assembly.GetManifestResourceStream(IMAGE_RESOURCE_PATH); var linkedImage = new LinkedResource(imageStream, "image/png"); linkedImage.ContentId = "IMAGE.PNG"; altView.LinkedResources.Add(linkedImage); // Get the attachment from an embedded resource. fileStream = assembly.GetManifestResourceStream(FILE_RESOURCE_PATH); var file = new Attachment(fileStream, MediaTypeNames.Application.Pdf); file.Name = "FILE.PDF"; msg.Attachments.Add(file); // Send the email var client = new SmtpClient(...); client.Credentials = new NetworkCredential(...); client.Send(msg); } finally { if (fileStream != null) fileStream.Dispose(); if (imageStream != null) imageStream.Dispose(); if (htmlStream != null) htmlStream.Dispose(); }
Я бы рекомендовал использовать какие-то шаблоны. Существуют различные способы приблизиться к этому, но по существу держите шаблон электронной почты где-то (на диске, в базе данных и т. д.) и просто вставьте ключевые данные (т. е. имя получателя и т. д.) В шаблон.
Это гораздо более гибко, потому что это означает, что вы можете изменить шаблон по мере необходимости без изменения кода. По моему опыту, вы можете получать запросы на изменения шаблонов от конечных пользователей. Если вы хотите пойти на всю свинью, вы можете включить редактор шаблонов.
Я использую dotLiquid именно для этой задачи.
он берет шаблон и заполняет специальные идентификаторы содержимым анонимного объекта.
//define template String templateSource = "<h1>{{Heading}}</h1>Dear {{UserName}},<br/><p>First part of the email body goes here"); Template bodyTemplate = Template.Parse(templateSource); // Parses and compiles the template source //Create DTO for the renderer var bodyDto = new { Heading = "Heading Here", UserName = userName }; String bodyText = bodyTemplate.Render(Hash.FromAnonymousObject(bodyDto));Он также работает с коллекциями, посмотреть некоторые онлайн примеры.
эмиссия handbuilt html, как это, вероятно, лучший способ до тех пор, пока разметка не слишком сложна. Stringbuilder только начинает окупать вас с точки зрения эффективности после примерно трех конкатенаций, поэтому для действительно простых вещей string + string будет делать.
кроме этого вы можете начать использовать элементы управления html (System.Сеть.ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.HtmlControls) и визуализировать их, таким образом, вы можете иногда наследовать их и сделать свой собственный класс для сложной условной компоновки.
вы можете взглянуть на некоторые из шаблонов фреймворков, которые доступны в данный момент. Некоторые из них являются побочными эффектами в результате MVC, но это не требуется. Искра - это хорошо.
Если вы не хотите зависимости от полной платформы .NET Framework, есть также библиотека, которая делает ваш код похожим:
string userName = "John Doe"; var mailBody = new HTML { new H(1) { "Heading Here" }, new P { string.Format("Dear {0},", userName), new Br() }, new P { "First part of the email body goes here" } }; string htmlString = mailBody.Render();это с открытым исходным кодом, вы можете скачать его с http://sourceforge.net/projects/htmlplusplus/
отказ от ответственности: я автор этой библиотеки, она была написана, чтобы решить ту же проблему точно - отправить HTML-письмо из приложения.
в качестве альтернативы MailDefinition, взгляните на RazorEngine https://github.com/Antaris/RazorEngine.
это выглядит как лучшее решение.
приписывается...
как отправить письмо с шаблоном электронной почты c#
например
using RazorEngine; using RazorEngine.Templating; using System; namespace RazorEngineTest { class Program { static void Main(string[] args) { string template = @"<h1>Heading Here</h1> Dear @Model.UserName, <br /> <p>First part of the email body goes here</p>"; const string templateKey = "tpl"; // Better to compile once Engine.Razor.AddTemplate(templateKey, template); Engine.Razor.Compile(templateKey); // Run is quicker than compile and run string output = Engine.Razor.Run( templateKey, model: new { UserName = "Fred" }); Console.WriteLine(output); } } }какие выходы...
<h1>Heading Here</h1> Dear Fred, <br /> <p>First part of the email body goes here</p>Здесь Заголовок
Уважаемый Фред,первая часть письма тело идет здесь
на и StackOverflow вопрос это содержит некоторые довольно исчерпывающие ответы. Лично я использую NVelocity как механизм шаблонов, который ранее пытался использовать ASP.Net движок для создания содержимого электронной почты html. NVelocity намного проще в использовании, обеспечивая при этом массу гибкости. Я обнаружил, что с помощью ASP.Net .aspx файлы для шаблонов работали, но имели некоторые непредвиденные побочные эффекты.
Comments