Есть ли лучший способ генерировать HTML-адрес электронной почты в С# (для отправки через 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>");
и т.д. и т.д.?
Ответ 1
Вы можете использовать класс MailDefinition.
Вот как вы его используете:
MailDefinition md = new MailDefinition();
md.From = "test@domain.com";
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("you@anywhere.com", replacements, body, new System.Web.UI.Control());
Кроме того, я написал сообщение в блоге о том, как создать тело электронной почты HTML в С# с использованием шаблонов, используя класс MailDefinition.
Ответ 2
Используйте класс System.Web.UI.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();
Ответ 3
Обновленный ответ:
Документация для SmtpClient
, класса, используемого в этом ответе, теперь читается: "Устаревший (" SmtpClient и его сеть типов плохо разработаны, мы настоятельно рекомендуем использовать https://github.com/jstedfast/MailKit и https://github.com/jstedfast/MimeKit вместо") '.
Источник: https://www.infoq.com/news/2017/04/MailKit-MimeKit-Official
Оригинальный ответ:
Использование класса MailDefinition - неправильный подход. Да, это удобно, но оно также примитивно и зависит от элементов управления веб-интерфейса - это не имеет смысла для чего-то, что обычно является задачей на стороне сервера.
Представленный ниже подход основан на документации MSDN и пост Qureshi на 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();
}
Ответ 4
Я бы рекомендовал использовать какие-то шаблоны. Существуют различные способы подхода к этому, но по существу содержат шаблон электронной почты, где (на диске, в базе данных и т.д.) И просто вставляйте ключевые данные (IE: имя получателей и т.д.) В шаблон.
Это намного более гибко, потому что это означает, что вы можете изменять шаблон по мере необходимости, не изменяя свой код. По моему опыту, вы можете получить запросы об изменениях в шаблонах от конечных пользователей. Если вы хотите пройти весь свиньи, вы можете включить редактор шаблонов.
Ответ 5
Я использую 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));
Он также работает с коллекциями, см. несколько онлайн-примеров.
Ответ 6
Испускать ручной html, как это, вероятно, лучший способ, пока разметка не слишком сложна. Строковый строитель только начинает возвращать вас с точки зрения эффективности после примерно трех конкатенаций, поэтому для действительно простых строк строка + строка будет делать.
Кроме того, вы можете начать использовать элементы управления html (System.Web.UI.HtmlControls) и визуализировать их, таким образом, вы можете иногда наследовать их и создавать свою собственную класификацию для сложного условного макета.
Ответ 7
Возможно, вам захочется взглянуть на некоторые рамки шаблонов, доступные на данный момент. Некоторые из них являются побочными эффектами в результате MVC, но это не требуется. Spark является хорошим.
Ответ 8
Если вам не нужна зависимость от полной .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-письмо из приложения.
Ответ 9
В качестве альтернативы MailDefinition просмотрите RazorEngine https://razorengine.codeplex.com/.
Это выглядит как лучшее решение.
Атрибут...
как отправить электронный шаблон wth электронной почты С#
Ответ 10
Ну, это действительно зависит от решения, как я его вижу. Я сделал все, чтобы автоматически захватывать пользовательский ввод и форматировать его из разных паттернов. Лучшее решение, которое я сделал с html-письмами, было фактически форматированием xml + xslt, так как мы знали ввод почты вверх.
Ответ 11
Это зависит от того, насколько сложны ваши требования. У меня когда-то было приложение, которое отображало таблицу в HTML-письме, и я использовал Gridview ASP.NET для визуализации строк конкатенации HTML для генерации таблицы, было бы грязно.
Ответ 12
cyberzed - я использовал аналогичный подход в прошлом (XML + XSLT) с хорошими результатами. Это обеспечивает большую гибкость и означает, что код не должен касаться точных данных, которые требуются электронной почтой (создайте XML-документ, содержащий всю необходимую информацию, и пусть XSLT выбирает бит, который он хочет.
Единственное, что я бы сказал, это то, что я обнаружил, что XSLT немного болит в головной боли, но я был в порядке, когда я прошел мимо первоначальной нечетности.
Ответ 13
Существует аналогичный вопрос fooobar.com/info/22472/..., в котором содержатся довольно полные ответы. Лично я использую NVelocity в качестве механизма шаблона, ранее пытавшегося использовать механизм ASP.Net для генерации html-содержимого электронной почты. NVelocity намного проще использовать, сохраняя при этом гибкость. Я обнаружил, что использование ASP.Net.aspx файлов для шаблонов работало, но имело некоторые непредвиденные побочные эффекты.