program tip

ASP.NET에서 HTML / 이메일 템플릿을 설정할 수 있습니까?

radiobox 2020. 8. 28. 07:20
반응형

ASP.NET에서 HTML / 이메일 템플릿을 설정할 수 있습니까?


나는 상당한 수의 이메일을 보낼 사이트를 만들고 있습니다. 머리글과 바닥 글 텍스트 또는 템플릿을 설정하여 사용자가 필요한 경우 이러한 이메일을 쉽게 편집 할 수 있도록하고 싶습니다.

C # 문자열 리터럴에 HTML을 포함하면보기 흉하고 이스케이프에 대해 걱정해야합니다. 머리글과 바닥 글에 플랫 파일을 포함하는 것은 작동 할 수 있지만 그에 대한 무언가는 옳지 않은 것 같습니다.

어떤 .ASPX식 으로든 페이지를 템플릿으로 사용한 다음 내 코드에 해당 페이지를 제공하도록 지시하고 이메일에 반환 된 HTML 을 사용하는 것이 이상적인 방법입니다 .

이 작업을 수행하는 좋고 쉬운 방법이 있습니까? 이 문제를 해결하는 더 좋은 방법이 있습니까?

업데이트 됨 :
표준 .aspx 페이지를 전자 메일 템플릿으로 사용할 수있는 답변을 추가했습니다. 평상시처럼 모든 변수를 교체하고 데이터 바인딩 등을 사용하십시오. 그런 다음 페이지의 출력을 캡처하고 짜잔! HTML 이메일이 있습니다!

UPDATED WITH CAVEAT !!! :
일부 aspx 페이지에서 MailDefinition 클래스를 사용하고 있었지만 실행중인 서버 프로세스 중에이 클래스를 사용하려고하면 실패했습니다. MailDefinition.CreateMailMessage () 메서드가 항상 뭔가를하는 것은 아니지만 참조 할 유효한 컨트롤이 필요하기 때문이라고 생각합니다. 이 때문에 aspx 페이지를 사용하는 내 접근 방식이나 ascx 페이지를 사용하는 Mun의 접근 방식을 권장합니다.


이미 여기에 많은 답변이 있지만 이메일 템플릿과 함께 Razor를 사용하는 방법에 대한 훌륭한 기사를 우연히 발견했습니다. Razor는 ASP.NET MVC 3으로 푸시되었지만 MVC는 Razor를 사용하는 데 필요하지 않습니다. 이것은 이메일 템플릿을 수행하는 매우 매끄러운 처리입니다.

기사에서 알 수 있듯이 "Razor의 가장 좋은 점은 이전 버전 (webforms)과 달리 웹 환경과 연결되어 있지 않기 때문에 웹 외부에서 쉽게 호스팅 할 수 있으며 다양한 목적의 템플릿 엔진으로 사용할 수 있다는 것입니다."

RazorEngine으로 HTML 이메일 생성-Part 01-소개

ASP.NET 외부에서 Razor 템플릿 활용 : 더 이상 HTML 용이 아닙니다!

RazorEngine을 사용하는 ASP.NET의 더 스마트 한 이메일 템플릿

유사한 Stackoverflow QA

새로운 RazorEngine API를 사용한 템플릿

MVC없이 Razor 사용

asp.net 외부에서 Razor View Engine을 사용할 수 있습니까?


컨트롤을로드 한 다음이를 문자열로 렌더링하고이를 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();

그런 다음 평소와 같이 이메일을 구성 할 수 있습니다.

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

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

사용자 정의 컨트롤에는 머리글 및 바닥 글과 같은 다른 컨트롤이 포함될 수 있으며 데이터 바인딩과 같은 기능도 활용할 수 있습니다.


MailDefinition 클래스를 사용해 볼 수 있습니다.


사용자 이름, 제품 이름 등과 같은 매개 변수를 전달하려면 오픈 소스 템플릿 엔진 NVelocity 를 사용하여 최종 이메일 / HTML을 생성 할 수 있습니다.

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

애플리케이션에서 MailTemplate.vm으로 메일 본문 생성 :

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

결과 메일 본문은 다음과 같습니다.

ScarletGarden 의 샘플 이메일 템플릿 .

Foreach 예 :

[날짜 : 12.02.2009] 이름 : 항목 1, 값 : 09

[날짜 : 2009 년 2 월 21 일] 이름 : 항목 4, 값 : 52

[날짜 : 2009 년 3 월 1 일] 이름 : 항목 2, 값 : 21

[날짜 : 2009 년 3 월 23 일] 이름 : 항목 6, 값 : 24

템플릿 편집을 위해 FCKEditor 를 사용 하고 템플릿을 파일에 저장할 수 있습니다.


Mail.dll 이메일 구성 요소 에는 이메일 템플릿 엔진이 포함됩니다.

구문 개요는 다음과 같습니다.

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

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

</body>
</html>

템플릿을로드하고 C # 개체에서 데이터를 채우고 이메일을 보내는 코드는 다음과 같습니다.

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

이메일 템플릿 엔진 블로그 게시물 에 대한 자세한 정보를 얻을 수 있습니다 .

또는 Mail.dll 전자 메일 구성 요소를 다운로드 하여 사용해보십시오.

이것은 내가 만든 상업용 제품입니다.


유연성이 전제 조건 중 하나 인 경우 XSLT가 좋은 선택 일 수 있습니다. 이는 .NET 프레임 워크에서 완벽하게 지원되며 사용자가 해당 파일을 편집하도록 할 수도 있습니다. 이 문서 ( http://www.aspfree.com/c/a/XML/XSL-Transformations-using-ASP-NET/ )는 시작에 유용 할 수 있습니다 (msdn에 대한 자세한 정보가 있음). ScarletGarden에서 말했듯이 NVelocity는 또 다른 좋은 선택이지만 "내장".NET 프레임 워크 지원과 플랫폼에 구애받지 않기 때문에 XSLT를 선호합니다.


다음과 같이 할 수도 있습니다.

.aspx 페이지를 만들고 OnLoad 메서드 끝에 넣거나 수동으로 호출합니다.

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

이것에 잠재적 인 문제가 있는지 확실하지 않지만 작동 할 것 같습니다. 이렇게하면 텍스트 대체 만 지원하는 MailDefinition 클래스 대신 모든 기능을 갖춘 .aspx 페이지를 사용할 수 있습니다.


물론 HTML 템플릿을 만들 수 있으며 텍스트 템플릿도 권장합니다. 템플릿에서 본문이 놓일 위치에 [BODY]를 넣은 다음 템플릿에서 읽기만하면 본문을 새 내용으로 바꿀 수 있습니다. .Nets Mail Class를 사용하여 이메일을 보낼 수 있습니다. 처음에 이메일을 만든 후 모든 수신자에게 이메일을 보내는 과정을 반복하면됩니다. 나를 위해 매력처럼 일했습니다.

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("address@gmail.com", "display name");
m.To.Add("address@gmail.com");
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);

다음은보다 복잡한 이메일 템플릿에 XSL 변환을 사용하는 또 다른 대안입니다 . .NET 애플리케이션에서 HTML 기반 이메일 보내기 .


이 작업을 수행 할 때주의해야합니다. SPAM 필터는 분명히 ViewState 때문에 ASP.net에서 생성 한 html을 차단하는 것처럼 보이므로 이렇게하려면 생성 된 Html이 깨끗한 지 확인하십시오.

개인적으로 Asp.net MVC를 사용하여 원하는 결과를 얻으려고합니다. 또는 NVelocity 는 이것에 아주 좋습니다


.ASPX 페이지를 템플릿으로 사용하는 것이 이상적인 것은 무엇입니까? 그런 다음 내 코드에 해당 페이지를 제공하도록 지시하고 이메일에 반환 된 HTML을 사용하십시오.

WebRequest를 쉽게 구성하여 ASPX 페이지에 도달하고 결과 HTML을 얻을 수 있습니다. 조금 더 작업하면 WebRequest 없이도 완료 할 수 있습니다. PageParser와 Response.Filter를 사용하면 페이지를 실행하고 출력을 캡처 할 수 있습니다 ...하지만 좀 더 우아한 방법이있을 수 있습니다.


매일 엄청난 수의 이메일을 보내야하는 프로젝트 중 하나에 비슷한 요구 사항이 있었고 클라이언트는 다양한 유형의 이메일에 대한 html 템플릿을 완벽하게 제어하기를 원했습니다.

많은 수의 이메일을 보내야하기 때문에 성능이 주요 관심사였습니다.

우리가 생각 해낸 것은 다양한 유형의 이메일에 대해 전체 html 템플릿 마크 업 ([UserFirstName], [UserLastName]과 같은 플레이스 홀더와 함께 런타임에 실제 데이터로 대체 됨)을 저장하는 SQL 서버의 정적 콘텐츠였습니다.

그런 다음이 데이터를 asp.net 캐시에로드했습니다. 따라서 html 템플릿을 반복해서 읽지 않지만 실제로 변경된 경우에만

우리는 클라이언트에게 관리자 웹 양식을 통해 이러한 템플릿을 수정할 수있는 WYSIWYG 편집기를 제공했습니다. 업데이트가있을 때마다 asp.net 캐시를 재설정합니다.

그리고 우리는 이메일 로그를위한 별도의 테이블을 가지고 있었는데, 여기서 보낼 모든 이메일이 기록되었습니다. 이 테이블에는 emailType, emailSent 및 numberOfTries라는 필드가 있습니다.

우리는 신속하게 전송해야하는 중요한 이메일 유형 (예 : 신규 회원 가입, 비밀번호 분실)에 대해 5 분마다 작업을 실행했습니다.

덜 중요한 이메일 유형 (예 : 프로모션 이메일, 뉴스 이메일 등)에 대해 15 분마다 다른 작업을 실행했습니다.

이렇게하면 서버가 멈추지 않는 이메일을 보내는 것을 차단하지 않고 메일을 일괄 처리합니다. 이메일이 전송되면 emailSent 필드를 1로 설정합니다.


aspx 및 ascx 솔루션에는 현재 HttpContext가 필요하므로 많은 작업 없이는 비동기 적으로 (예 : 스레드에서) 사용할 수 없습니다.


쉬운 대답은 MvcMailer라고 생각합니다. 선호하는보기 엔진을 사용하여 이메일을 생성 할 수있는 NuGet 패키지입니다. 여기 에서 NuGet 패키지 프로젝트 문서를 참조하세요.

도움이 되었기를 바랍니다.


DotLiquid는 또 다른 옵션입니다. 클래스 모델에서 값을 지정한 {{ user.name }}다음 런타임에 해당 클래스의 데이터와 마크 업이있는 템플릿을 제공하면 값이 병합됩니다. 여러면에서 Razor 템플릿 엔진을 사용하는 것과 유사합니다. 루프와 같은 더 복잡한 것들과 ToUpper와 같은 다양한 기능을 지원합니다. 좋은 점은 템플릿을 만든 사용자가 razor 에서처럼 시스템을 손상 시키거나 안전하지 않은 코드를 작성할 수 없도록 "안전"하다는 것입니다. http://dotliquidmarkup.org/try-online


읽기 및 파일을 작성하는 ASPNET 및 관련 사용자 권한을 허용 할 수 있다면, 당신은 쉽게 표준 HTML 파일 사용할 수 있습니다 String.Format()자리 ( {0}, {1:C}이러한 목표를 달성하는 등).

System.IO네임 스페이스의 클래스를 사용하여 파일에서 문자열로 읽기만하면됩니다 . 해당 문자열이 있으면에 대한 첫 번째 인수로 전달 String.Format()하고 매개 변수를 제공합니다.

해당 문자열을 유지하고 전자 메일 본문으로 사용하면 기본적으로 완료됩니다. 우리는 오늘날 수십 개의 (분명히 작은) 사이트에서이 작업을 수행하며 문제가 없었습니다.

(a) 한 번에 수백만 개의 이메일을 보내지 않고, (b) 각 이메일을 개인화하지 않는 경우 (그렇지 않으면 많은 문자열을 먹지 않는 경우), (c ) HTML 파일 자체는 상대적으로 작습니다.


이메일 메시지 IsBodyHtml = true 설정

이메일 콘텐츠가 포함 된 개체를 가져옵니다. 개체를 직렬화하고 xml / xslt를 사용하여 html 콘텐츠를 생성합니다.

AlternateViews를 수행하려면 jmein이 다른 xslt 템플릿을 사용하여 일반 텍스트 콘텐츠를 만드는 것과 동일한 작업을 수행하십시오.

이것의 주요 이점 중 하나는 레이아웃을 변경하려는 경우 xslt 템플릿을 업데이트하기 만하면된다는 것입니다.


SubSonic (www.subsonicproject.com)을보십시오. 코드를 생성하기 위해 정확히이 작업을 수행하고 있습니다. 템플릿은 표준 ASPX이며 c #을 출력합니다. 시나리오에 동일한 방법을 재사용 할 수 있습니다.


TemplateMachine 과 같은 템플릿 라이브러리를 사용합니다 . 이를 통해 대부분의 경우 이메일 템플릿을 일반 텍스트와 함께 넣은 다음 규칙을 사용하여 필요에 따라 값을 삽입 / 교체 할 수 있습니다. Ruby의 ERB와 매우 유사합니다. 이를 통해 ASPX 등과 같은 것에 너무 많이 묶이지 않고 메일 콘텐츠 생성을 분리 할 수 ​​있습니다. 그런 다음 콘텐츠가 생성되면 이메일을 보낼 수 있습니다.


나는 Raj의 대답을 좋아합니다. ListManager와 같은 프로그램 및 DNN과 같은 프레임 워크는 유사한 작업을 수행하며, 비전문 사용자가 쉽게 편집해야하는 경우 SQL에 저장된 HTML을 수정하는 WYSIWYG 편집기는 가장 쉽고 간단한 방법이며 바닥 글과 독립적으로 편집 헤더를 쉽게 수용 할 수 있습니다. 토큰을 사용하여 동적으로 값을 삽입합니다.

위의 방법 (또는 실제로)을 사용하는 경우 명심해야 할 한 가지는 편집자가 삽입 할 수있는 스타일 및 태그 유형에 대해 엄격하고주의하는 것입니다. 브라우저가 까다 롭다고 생각되면 이메일 클라이언트가 동일한 것을 어떻게 다르게 렌더링하는지 확인할 때까지 기다리십시오.


Canavar의 답변과 비슷하지만 NVelocity 대신 항상 구성 파일에서 템플릿을로드하거나 File.ReadAllText ()를 사용하여 외부 파일을로드하고 값을 설정하는 " StringTemplate "을 사용합니다.

Java 프로젝트이지만 C # 포트는 견고하고 여러 프로젝트에서 사용했습니다 (외부 파일의 템플릿을 사용하여 이메일 템플릿에 사용했습니다).

대안은 항상 좋습니다.


다음은 WebClient 클래스를 사용하는 간단한 방법입니다 .

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

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

    return htmlBody;
}

그런 다음 다음과 같이 호출하십시오.

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

물론 대부분의 이메일 클라이언트 (예 : Outlook)에서 웹 페이지의 스타일을 표시하려면 CSS를 인라인해야합니다. 이메일에 동적 콘텐츠 (예 : 고객 이름)가 표시되는 경우 웹 사이트에서 QueryStrings를 사용하여 데이터를 채우는 것이 좋습니다. (예 : http://www.yourwebsite.com?CustomerName=Bob )


@bardev는 좋은 솔루션을 제공하지만 안타깝게도 모든 경우에 이상적이지는 않습니다. 내 것이 그들 중 하나였습니다.

VS 2013에서 웹 사이트에서 WebForms를 사용하고 있습니다 (다시는 웹 사이트를 사용하지 않겠다고 맹세합니다. PITA).

Razor 제안을 시도했지만 내 웹 사이트는 IDE가 MVC 프로젝트에서 제공하는 가장 중요한 IntelliSense를 얻지 못했습니다. 또한 UserControl을위한 완벽한 장소 인 템플릿에 디자이너를 사용하고 싶습니다.

다시 Razor의 Nix.

그래서 대신이 작은 프레임 워크를 생각해 냈습니다 (UserControl의 경우 @mun, Strong Typing의 경우 @imatoria에 대한 모자 팁). 내가 볼 수있는 유일한 잠재적 문제 지점은 .ASCX 파일 이름을 클래스 이름과 동기화되도록주의해야한다는 것입니다. 길을 잃으면 런타임 오류가 발생합니다.

FWIW : 테스트에서 적어도 RenderControl () 호출은 Page 컨트롤을 좋아하지 않으므로 UserControl을 사용했습니다.

여기에 모든 것을 포함 시켰습니다. 내가 빠진 것이 있으면 알려주세요.

HTH

용법:

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} <james.bond@mi6.co.uk>".ToFormat(oTemplate.Name), "Purchase Receipt", oTemplate.ToHtml)
  End Sub
End Class

기본 클래스 :

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"클래스 :

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

템플릿 클래스 :

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 헤더 :

<%@ 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 바닥 글 :

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

</body>
</html>

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

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

도우미 :

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

내가 사용하는 라이브러리를 믹스에 던지십시오 : https://github.com/lukencode/FluentEmail

RazorLight 를 사용 하여 이메일을 렌더링 하고, 유창한 스타일을 사용 하여 이메일을 작성하고 , 여러 발신자를 즉시 ​​지원합니다. ASP.NET DI에 대한 확장 메서드도 함께 제공됩니다. 사용이 간단하고 설정이 거의 없으며 일반 텍스트 및 HTML 지원이 제공됩니다.

참고 URL : https://stackoverflow.com/questions/620265/can-i-set-up-html-email-templates-with-asp-net

반응형