programing tip

C #에서 HTML 이메일 본문 생성

itbloger 2020. 8. 5. 07:56
반응형

C #에서 HTML 이메일 본문 생성


Stringbuilder를 사용하여 다음을 수행하는 것보다 C.에서 HTML 전자 메일을 생성하는 더 좋은 방법이 있습니까 (System.Net.Mail을 통해 보내는 경우)?

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

등등 등등?


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

또한 MailDefinition 클래스를 사용하여 템플릿을 사용하여 C #에서 HTML 전자 메일 본문생성 하는 방법에 대한 블로그 게시물을 작성했습니다 .


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

업데이트 된 답변 :

SmtpClient이 답변에 사용 된 클래스에 대한 설명서는 이제 'Obsolete ( "SmtpClient 및 해당 유형의 네트워크가 제대로 설계되지 않았습니다. https://github.com/jstedfast/MailKithttps : // github 를 사용하는 것이 좋습니다 . .com / jstedfast / MimeKit ") ').

출처 : https://www.infoq.com/news/2017/04/MailKit-MimeKit-Official

원래 답변 :

MailDefinition 클래스를 사용하는 것은 잘못된 접근법입니다. 예, 편리하지만 기본적이며 웹 UI 컨트롤에 의존합니다. 일반적으로 서버 측 작업에 적합하지 않습니다.

아래 제시된 접근 방식은 MSDN 문서 및 CodeProject.com에 대한 Qureshi의 게시물을 기반으로 합니다.

참고 :이 예제는 포함 된 리소스에서 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();
}

어떤 종류의 템플릿을 사용하는 것이 좋습니다. 이것에 접근하는 방법에는 여러 가지가 있지만 본질적으로 전자 메일의 템플릿을 디스크의 어떤 위치 (데이터베이스 등)에 보관하고 키 데이터 (IE : 수신자 이름 등)를 템플릿에 삽입하면됩니다.

코드를 변경하지 않고도 필요에 따라 템플릿을 변경할 수 있기 때문에 훨씬 유연합니다. 내 경험상 최종 사용자로부터 템플릿 변경 요청을받을 가능성이 높습니다. 전체 돼지를 원한다면 템플릿 편집기를 포함시킬 수 있습니다.


정확히이 작업에 dotLiquid사용 합니다.

It takes a template, and fills special identifiers with the content of an anonymous object.

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

It also works with collections, see some online examples.


Emitting handbuilt html like this is probably the best way so long as the markup isn't too complicated. The stringbuilder only starts to pay you back in terms of efficiency after about three concatenations, so for really simple stuff string + string will do.

Other than that you can start to use the html controls (System.Web.UI.HtmlControls) and render them, that way you can sometimes inherit them and make your own clasess for complex conditional layout.


As an alternative to MailDefinition, have a look at RazorEngine https://github.com/Antaris/RazorEngine.

This looks like a better solution.

Attributted to...

how to send email wth email template c#

E.g

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

Which outputs...

<h1>Heading Here</h1>
Dear Fred,
<br />
<p>First part of the email body goes here</p>

Heading Here

Dear Fred,

First part of the email body goes here


You might want to have a look at some of the template frameworks that are available at the moment. Some of them are spin offs as a result of MVC but that isn't required. Spark is a good one.


If you don't want a dependency on the full .NET Framework, there's also a library that makes your code look like:

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

It's open source, you can download it from http://sourceforge.net/projects/htmlplusplus/

Disclaimer: I'm the author of this library, it was written to solve the same issue exactly - send an HTML email from an application.


There is similar StackOverflow question that contains some fairly comprehensive responses. Personally I use NVelocity as the template engine having previously tried using the ASP.Net engine to generate html email content. NVelocity is a lot simpler to use while still providing tons of flexibility. I found that using ASP.Net .aspx files for templates worked but had some unanticipated side effects.

참고URL : https://stackoverflow.com/questions/886728/generating-html-email-body-in-c-sharp

반응형