Чи можу я налаштувати шаблони HTML / електронної пошти за допомогою ASP.NET?


97

Я працюю над сайтом, який надсилатиме значну кількість електронних листів. Я хочу налаштувати як текст верхнього, так і нижнього колонтитула, або, можливо, навіть шаблони, щоб дозволити користувачам легко редагувати ці електронні листи, якщо це потрібно.

Якщо я вбудую HTML всередину рядкових літералів C #, це негарно, і їм доведеться турбуватися про те, щоб уникнути. Включення плоских файлів для верхнього та нижнього колонтитулів може працювати, але щось у цьому просто не здається правильним.

Що було б ідеальним, .ASPXякби якось використовувати сторінку як шаблон, тоді просто скажіть моєму коду, щоб він обслуговував цю сторінку, і використовуйте HTML-код, повернутий для електронної пошти.

Чи є приємний і простий спосіб це зробити? Чи є кращий спосіб вирішити цю проблему?

Оновлено:
я додав відповідь, яка дозволяє використовувати стандартну сторінку .aspx як шаблон електронної пошти. Просто замініть усі змінні, як зазвичай, використовуйте прив'язку даних і т. Д. Тоді просто захопіть результат сторінки і вуаля! У вас є електронна пошта HTML!

ОНОВЛЕНО CAVEAT !!!:
Я використовував клас MailDefinition на деяких сторінках aspx просто чудово, але при спробі використовувати цей клас під час запущеного серверного процесу він не вдався. Я вважаю, що це було тому, що метод MailDefinition.CreateMailMessage () вимагає дійсного елемента керування для посилання, хоча він не завжди щось робить. Через це я б рекомендував свій підхід із використанням сторінки aspx або підхід Мун із використанням сторінки ascx, що здається трохи кращим.


Іншим рішенням буде використання AlphaMail для створення та надсилання електронних листів за допомогою C # та мови шаблонів Comlang .
Тімоті Е. Йоханссон

1
@JohnBubriski: Я працюю навколо проблеми управління ви згадали в «ОНОВЛЕННЯ з ризикованими» з використанням , new System.Web.UI.Control()як в: mailDefinition.CreateMailMessage("somebody@fake.com", iDictionaryReplacements, new System.Web.UI.Control()).
Теофіл

Так, я теж це робив, але, зважаючи на появу Razor, це стає менш гарною ідеєю.
Джон Бубріскі

Відповіді:


73

Тут вже є маса відповідей, але я натрапив на чудову статтю про те, як використовувати Razor із шаблоном електронної пошти. Razor було натиснуто за допомогою ASP.NET MVC 3, але MVC не потрібно використовувати Razor. Це досить гладка обробка шаблонів електронної пошти

Як зазначено в статті, "Найкраще у Razor - це те, що на відміну від свого попередника (веб-форм) він не пов'язаний з веб-середовищем, ми можемо легко розмістити його поза Інтернетом і використовувати як механізм шаблонів для різних цілей".

Створення електронних листів HTML за допомогою RazorEngine - Частина 01 - Вступ

Використовуючи шаблони бритви поза ASP.NET: вони більше не просто для HTML!

Розумніші шаблони електронної пошти в ASP.NET за допомогою RazorEngine

Схожий QA Stackoverflow

Шаблонування за допомогою нового API RazorEngine

Використання бритви без MVC

Чи можна використовувати Razor View Engine за межами asp.net


1
+1, але будьте обережні, якщо користувачі надають шаблони, оскільки вони можуть запускати код C # із шаблону, надаючи їм набагато більше енергії у вашій системі, ніж ви, мабуть, хотіли б.
AaronLS

Що ви думаєте про безпеку. Використання цього механізму створення шаблонів дозволяє, можливо, форматувати всю файлову систему. Мені подобається двигун, але це змушує мене подивитися на інші двигуни.
der_chirurg

55

Ви також можете спробувати завантажити елемент керування, а потім відтворити його в рядок і встановити як тіло 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);

Елемент керування користувача може містити інші елементи керування, такі як верхній і нижній колонтитули, а також скористатися перевагами таких функцій, як прив'язка даних.


Я якось пропустив цю відповідь вперше ... приємно. Подібно до мого рішення, але з ascx замість aspx. Я все ще думаю, що aspx було б краще, оскільки він пропонував би цілу сторінку, а не елемент керування, але це саме те, що я думаю.
Джон Бубріскі

Так, ви можете використовувати будь-яке рішення ... Вони працюють однаково. Одна з переваг такого підходу - послідовність. Наприклад, ви можете показати користувачеві підсумок замовлення та включити точно те саме в електронний лист із підтвердженням, повторно використовуючи той самий елемент керування.
Mun

Незначна точка, але вам не вистачає рядка для оголошення StringBuilder у першому блоці коду.
Кіршштайн

9
Приклад не пояснює, де знаходиться код, це сторінка ?, оскільки LoadControl - це метод сторінки / управління.
Shrage Smilowitz

@Mun, Ви завантажуєте usercontrol у змінну, яка називається ctrl, і більше ніколи не посилаєтеся на неї у своєму коді. Як це має працювати?
Людина-булочка

35

Ви можете спробувати клас MailDefinition


4
Я просто хочу зазначити, що це добре для основних електронних листів, але не для чогось складного. Клас MailDefinition не підтримує прив'язку даних. Єдине, що він насправді робить, це пропонує заміну рядків. Хоча це також вбудовано в Майстер створення облікових записів членів.
Джон Бубріскі

4
Клас MailDefinition повинен отримати Control для відтворення шаблонного вмісту .. Не дуже добре.
Юкі,

17

Якщо ви хочете передати такі параметри, як імена користувачів, назви продуктів, ... тощо, ви можете використовувати двигун шаблону з відкритим вихідним кодом 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 .

Приклад для кожного:

[Дата: 12.02.2009] Назва: Пункт 1, Значення: 09

[Дата: 21.02.2009] Назва: Пункт 4, Значення: 52

[Дата: 01.03.2009] Назва: Пункт 2, Значення: 21

[Дата: 23.03.2009] Назва: Пункт 6, Значення: 24

Для редагування шаблонів, можливо, ви можете використовувати FCKEditor і зберегти свої шаблони у файлах.


7

Електронний компонент 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 і спробуйте.

Зверніть увагу, що це комерційний продукт, який я створив.


6

Якщо гнучкість є однією з ваших передумов, XSLT може бути хорошим вибором, який повністю підтримується .NET framework, і ви зможете навіть дозволити користувачеві редагувати ці файли. Ця стаття ( http://www.aspfree.com/c/a/XML/XSL-Transformations-using-ASP-NET/ ) може бути корисною для початку (msdn має про це більше інформації). Як сказав ScarletGarden, NVelocity - ще один хороший вибір, але я віддаю перевагу XSLT за його "вбудовану" підтримку .NET framework та агностик платформи.


Я ніколи раніше не думав про це, але, спробувавши безліч інших методів, я виявив, що це чудово працює в поєднанні з додаванням IXmlSerializableінтерфейсу до моїх класів. Всього за кілька рядків я можу передати свій клас електронною поштою.
cjbarth

Урф, мені снилися кошмари про XSLT. Можливо, найнеінтуїтивніша мова програмування / розмітки, з якою я працював. І неможливо підтримувати для інших і навіть для себе через 1 місяць після першого кодування вашого XSLT.
PussInBoots

5

Я думаю, ви також можете зробити щось подібне:

Створіть сторінку та .aspx, і поставте це в кінці методу OnLoad або викличте його вручну.

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

Я не впевнений, чи є з цим якісь потенційні проблеми, але, схоже, це спрацювало б. Таким чином, ви можете використовувати повнофункціональну сторінку .aspx замість класу MailDefinition, який підтримує лише текстові заміни.


Хоча клас MailDefinition є хорошим початком, він трохи елементарний. Цей метод повинен підтримувати набагато більше функцій, таких як прив'язка даних і, можливо, навіть трасування. Будь-які думки з цього приводу чи потенційні проблеми?
Джон Бубріскі

Чудово! Чи виникали у вас проблеми з цим?
Іван Бубріскі

Отже, ви дозволите своїм користувачам редагувати файли .aspx, коли їм потрібно внести зміни до шаблону пошти? Я б назвав це потенційним питанням.
Брайан

Я не думаю, що так, принаймні, не більший ризик, ніж інші шаблони, які вони можуть редагувати. Звичайно, якщо вони знали, що роблять, вони могли завдати шкоди, але, принаймні, у цьому випадку це малоймовірно. Це не була б складна сторінка .aspx, більше шаблон із заповнювачами.
Іван Бубріскі

Минув якийсь час, я знаю, але ви пам’ятаєте своє остаточне рішення? Мені не вдалося отримати такий конкретний підхід до роботи з Page, принаймні, при використанні загального методу розширення для візуалізації. Таким чином я перейшов на UserControl; див. мою відповідь нижче. Поки, здається, це працює добре ... Мені було б цікаво дізнатись, як ви працювали у той час.
InteXX

4

Звичайно, ви можете створити 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);

Ви можете вирізати речі StreamReader і замінити на File.ReadAllText (шлях)
Джон Шин

Це хороший початок, але забезпечує лише функціональність для верхнього та нижнього колонтитула. Це насправді не допомагає самому організму.
Джон Бубріскі

Основною частиною всього, що вам потрібно зробити, - це ввести вміст тіла, який є потрібним, у поля HTMLBody та TextBody, або ви можете, звичайно, також зберігати їх у файлах
Джош Мейн,

4

Ось ще одна альтернатива, яка використовує перетворення XSL для більш складних шаблонів електронної пошти: Надсилання електронної пошти на основі HTML із програм .NET .


2
Як посилання. Дякую! Мій мозок почав обертатися і зрозумів, що я можу зробити це на 1 крок далі і мати шаблон XSLT, який приймає об’єкт, що серіалізується XML, або контракт даних WCF прямо у формат HTML-електронної пошти. Раптом у мене з’являться шаблони електронної пошти із сильним набором тексту через фактичні серіалізуються класи!
CodingWithSpike

2

Будьте обережні, роблячи це, спам-фільтри, здається, блокують HTML-файл, створений ASP.net, мабуть, через ViewState, тому, якщо ви збираєтеся це зробити, переконайтеся, що створений HTML-файл чистий.

Я особисто хотів би розглянути можливість використання Asp.net MVC для досягнення бажаних результатів. або NVelocity в цьому досить непоганий


1

Що було б ідеально, як якось використовувати сторінку .ASPX як шаблон, а потім просто скажіть мій код для обслуговування цієї сторінки та використовуйте HTML, повернутий для електронної пошти.

Ви можете легко створити WebRequest для потрапляння на сторінку ASPX і отримати результуючий HTML. Трохи більше роботи, можливо, ви зможете зробити це без WebRequest. PageParser і Response.Filter дозволять вам запускати сторінку і фіксувати вихідні дані ... хоча можуть бути і деякі більш елегантні способи.


1

у мене була однакова вимога щодо одного з проектів, де вам доводилося надсилати величезну кількість електронних листів щодня, і клієнт хотів отримати повний контроль над HTML-шаблонами для різних типів електронних листів.

через велику кількість електронних листів, що надсилаються, продуктивність була головною проблемою.

ми придумали статичний вміст на сервері sql, де ви зберігаєте всю розмітку HTML-шаблону (разом із власниками місць, як [UserFirstName], [UserLastName], які замінюються реальними даними під час виконання) для різних типів електронних листів

потім ми завантажили ці дані в кеш asp.net - тому ми не читаємо шаблони html знову і знову - але лише тоді, коли вони насправді змінені

ми надали клієнту редактор WYSIWYG для модифікації цих шаблонів через веб-форму адміністратора. щоразу, коли були зроблені оновлення, ми скидаємо кеш asp.net.

а потім у нас була окрема таблиця для журналів електронної пошти - де реєструвалось кожне електронне повідомлення, яке слід надіслати. у цій таблиці були поля під назвою emailType, emailSent та numberOfTries.

ми просто запускали роботу кожні 5 хвилин для важливих типів електронної пошти (наприклад, реєстрація нового учасника, забутий пароль), яку потрібно надіслати якомога швидше

ми запускали іншу роботу кожні 15 хвилин для менш важливих типів електронної пошти (наприклад, електронної пошти з рекламою, електронної пошти з новинами тощо)

таким чином, ви не блокуєте сервер, що надсилає нон-стоп електронні листи, і ви обробляєте повідомлення в пакетному режимі. Після надсилання електронного листа ви встановите поле emailSent на 1.


Але як ви поводились з колекціями?
Рірі

1
Я теж це робив, і це спрацювало добре. Крім того, ви можете історично повернутися назад і переглянути записи надісланих електронних листів, якщо звіти - це ваша справа.
Mark Glorie

1

Зверніть увагу, що рішення aspx та ascx вимагають поточного HttpContext, тому не можуть використовуватися асинхронно (наприклад, у потоках) без великої роботи.


1

Я думаю, що проста відповідь - MvcMailer. Це пакет NuGet, який дозволяє використовувати ваш улюблений механізм перегляду для створення електронних листів. Дивіться пакет NuGet тут і документацію проекту

Сподіваюся, це допомагає!


Хм, дивно, але ця відповідь не привернула такої уваги ?!
PussInBoots

1

DotLiquid - ще один варіант. Ви вказуєте значення з моделі класу як, {{ user.name }}а потім під час виконання ви надаєте дані цього класу та шаблон із розміткою, і вони об'єднують значення для вас. Це багато в чому схоже на використання механізму шаблонування Razor. Він підтримує більш складні речі, такі як цикли та різні функції, такі як ToUpper. Приємно, що вони є "безпечними", тому користувач, який створює шаблони, не може зірвати вашу систему або написати небезпечний код, як у бритві: http://dotliquidmarkup.org/try-online


0

Якщо ви можете дозволити ASPNET та пов'язаним користувачам дозвіл читати та писати файл, ви можете легко використовувати файл HTML зі стандартними String.Format()заповнювачами ( {0},{1:C} і т.д.) для досягнення цієї мети .

Просто читайте у файлі як рядок, використовуючи класи з System.IOпростору імен. Отримавши цей рядок, передайте його як перший аргументString.Format() і вкажіть параметри.

Тримайте цей рядок навколо та використовуйте його як тіло електронного листа, і ви по суті готові. Ми робимо це на десятках (правда, невеликих) сайтів сьогодні, і жодних проблем не було.

Я повинен зауважити, що це найкраще працює, якщо (а) ви не надсилаєте мільйони електронних листів одночасно, (б) ви не персоналізуєте кожен електронний лист (інакше ви з’їдаєте тонну рядків) та (с ) сам файл HTML відносно невеликий.


0

Встановіть набір повідомлення електронної пошти IsBodyHtml = true

Візьміть свій об’єкт, що містить вміст електронної пошти. Серіалізуйте об’єкт і використовуйте xml / xslt для створення HTML-вмісту.

Якщо ви хочете зробити AlternateViews, зробіть те саме, що jmein використовує лише інший шаблон xslt для створення простого текстового вмісту.

одна з головних переваг цього - якщо ви хочете змінити макет, все, що вам потрібно зробити, оновити шаблон xslt.


0

Подивіться на SubSonic (www.subsonicproject.com). Вони роблять саме це для генерації коду - шаблон є стандартним ASPX, і він виводить c #. Той самий метод буде повторно використаний для вашого сценарію.


0

Я б використовував бібліотеку шаблонів, як TemplateMachine . це дозволяє в основному скласти шаблон електронної пошти разом із звичайним текстом, а потім використовувати правила для введення / заміни значень за необхідності. Дуже схожий на ERB у Ruby. Це дозволяє розділити генерацію поштового вмісту, не прив'язуючи вас занадто сильно до чогось типу ASPX тощо. Тоді, як тільки вміст буде створено за допомогою цього, ви можете надіслати електронною поштою.


0

Мені подобається відповідь Раджа. Такі програми, як ListManager та фреймворки, такі як DNN, роблять подібні речі, і якщо потрібне легке редагування нетехнічними користувачами, редактори WYSIWYG для модифікації HTML, що зберігається в SQL, є переважно простим і простим способом, і вони можуть легко розміщувати редагування заголовків незалежно від колонтитулів, тощо, а також використання токенів для динамічної вставки значень.

Одне, про що слід пам’ятати, використовуючи вищезазначений метод (або будь-який, насправді), - це бути суворим і обережним щодо типів стилів та тегів, які ви дозволяєте вставляти редакторам. Якщо ви вважаєте, що веб-переглядачі вигадливі, просто зачекайте, поки ви побачите, як по-різному клієнти електронної пошти надають одне і те ж ...


0

Подібно до відповіді Канавара, але замість NVelocity я завжди використовую " StringTemplate ", який завантажую шаблон із конфігураційного файлу, або завантажую зовнішній файл за допомогою File.ReadAllText () і встановлюю значення.

Це проект Java, але порт C # надійний, і я використовував його в декількох проектах (просто використовував його для шаблонування електронної пошти за допомогою шаблону у зовнішньому файлі).

Альтернативи завжди хороші.


0

Ось простий спосіб використання класу 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);

Звичайно, ваш CSS потрібно буде вбудувати, щоб показати стилі веб-сторінки у більшості клієнтів електронної пошти (наприклад, Outlook). Якщо у вашій електронній пошті відображається динамічний вміст (наприклад, ім'я клієнта), я рекомендую використовувати QueryStrings на своєму веб-сайті для заповнення даних. (наприклад, http://www.yourwebsite.com?CustomerName=Bob )


Акуратно, хоча я думаю, що більшість інших відповідей роблять це, не надсилаючи веб-запит на сайт, тобто не потрібно розміщувати тіло електронної пошти на вашому сайті.
Rup

@Rup Зрозуміло, але майте на увазі, багато разів люди хочуть побачити "веб-версію" електронного листа. Це рішення ідеально підходить для цього сценарію.
ROFLwTIME

0

@bardev пропонує хороше рішення, але, на жаль, воно не ідеально у всіх випадках. Моя була однією з них.

Я використовую WebForms на веб-сайті (клянусь, я більше ніколи не використовуватиму веб-сайт - що таке PITA) у VS 2013.

Я спробував пропозицію Razor, але, будучи веб-сайтом, я не отримав найважливішого IntelliSense, який IDE забезпечує в проекті MVC. Я також люблю використовувати дизайнер для своїх шаблонів - ідеальне місце для UserControl.

Знову Nix на Бритві.

Тож я натомість придумав цей маленький фреймворк (підказки для @mun для UserControl та @imatoria для Strong Typing). Приблизно єдине потенційне місце неполадок, яке я бачу, полягає в тому, що ви повинні бути обережними, щоб синхронізувати своє ім’я файлу .ASCX з назвою класу. Якщо ви заблукаєте, ви отримаєте помилку виконання.

FWIW: Під час мого тестування принаймні виклику RenderControl () не подобається елемент керування сторінкою, тому я пішов із 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

Клас "Фабрика":

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

0

Просто кинувши бібліотеку, яку я використовую, у мікс: https://github.com/lukencode/FluentEmail

Він відображає електронні листи за допомогою RazorLight , використовує вільний стиль для створення електронних листів та підтримує декілька відправників. Він також постачається із методами розширення для ASP.NET DI. Простий у використанні, невелика настройка, з підтримкою простого тексту та HTML.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.