ASP.NET ile HTML / E-posta Şablonları kurabilir miyim?


97

Önemli sayıda e-posta gönderecek bir site üzerinde çalışıyorum. Kullanıcıların ihtiyaç duyduklarında bu e-postaları kolayca düzenlemelerine izin vermek için hem üstbilgi hem de altbilgi metni veya hatta şablonlar oluşturmak istiyorum.

HTML'yi C # dizesi değişmez değerlerinin içine yerleştirirsem, bu çirkin ve kaçma konusunda endişelenmeleri gerekir. Üstbilgi ve altbilgi için düz dosyalar dahil etmek işe yarayabilir, ancak bununla ilgili bir şeyler doğru gelmiyor.

Bir .ASPXsayfayı bir şekilde şablon olarak kullanmak ideal ne olurdu , sonra koduma o sayfayı sunmasını söyleyin ve e-posta için döndürülen HTML'yi kullanın.

Bunu yapmanın güzel ve kolay bir yolu var mı? Bu sorunu çözmenin daha iyi bir yolu var mı?

Güncellendi:
E-posta şablonu olarak standart bir .aspx sayfası kullanmanızı sağlayan bir yanıt ekledim. Normalde yaptığınız gibi tüm değişkenleri değiştirin, veri bağlama vb. Kullanın. Sonra sayfanın çıktısını yakalayın ve işte! HTML e-postanız var!

CAVEAT İLE GÜNCELLENDİ !!!:
MailDefinition sınıfını bazı aspx sayfalarında kullanıyordum, ancak bu sınıfı çalışan bir sunucu işlemi sırasında kullanmaya çalışırken başarısız oldu. MailDefinition.CreateMailMessage () yönteminin her zaman bir şey yapmasa da başvurmak için geçerli bir denetim gerektirdiğine inanıyorum. Bu nedenle, yaklaşımımı bir aspx sayfası kullanarak veya Mun'un bir ascx sayfası kullanarak yaklaşımını tavsiye ederim, bu biraz daha iyi görünüyor.


Başka bir çözüm de AlphaMail'i C # ve Comlang şablon dilini kullanarak e-postalarınızı oluşturmak ve göndermek için kullanmak olacaktır .
Timothy E. Johansson

1
@JohnBubriski: Eğer bahsedilen kontrol sorunu ben işin kullanılmasına "ihtar ile GÜNCELLEME" new System.Web.UI.Control()olduğu gibidir: mailDefinition.CreateMailMessage("somebody@fake.com", iDictionaryReplacements, new System.Web.UI.Control()).
Theophilus

Evet, bunu ben de yaptım, ancak Razor'un ortaya çıkışı düşünüldüğünde, bu daha az iyi bir fikir haline geliyor.
John Bubriski

Yanıtlar:


73

Zaten burada bir sürü cevap var, ancak Razor'u e-posta şablonuyla nasıl kullanacağıma dair harika bir makaleye rastladım. Razor, ASP.NET MVC 3 ile itildi, ancak Razor kullanmak için MVC gerekli değildir. Bu, e-posta şablonları yapmanın oldukça düzgün bir işlemidir

Makalenin belirttiği gibi, "Razor'un en iyi yanı, öncülünden (web formları) farklı olarak web ortamına bağlı olmamasıdır, onu web dışında kolayca barındırabilir ve çeşitli amaçlar için şablon motoru olarak kullanabiliriz."

RazorEngine ile HTML e-postaları oluşturma - Bölüm 01 - Giriş

ASP.NET Dışındaki Razor Şablonlarından Yararlanma: Artık Sadece HTML için Değil!

RazorEngine ile ASP.NET'te daha akıllı e-posta şablonları

Benzer Stackoverflow QA

Yeni RazorEngine API kullanarak şablon oluşturma

Razor'u MVC olmadan kullanma

Razor View Engine'i asp.net dışında kullanmak mümkün mü


1
+1 ancak kullanıcılar şablonları sağlıyorlarsa dikkatli olun, çünkü şablondan C # kodunu çalıştırabilirler, bu da onlara sisteminizde muhtemelen isteyeceğinizden çok daha fazla güç sağlar.
AaronLS

Güvenlik hakkında ne düşünüyorsunuz? Bu şablon oluşturma motorunu kullanmak, tüm dosya sistemini biçimlendirmeyi mümkün kılar. Motoru beğendim ama bu beni diğer motorlara bakmaya zorluyor.
der_chirurg

55

Ayrıca bir denetimi yüklemeyi ve ardından onu bir dizeye dönüştürmeyi ve bunu HTML Gövdesi olarak ayarlamayı da deneyebilirsiniz:

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

Daha sonra e-postanızı her zamanki gibi oluşturabilirsiniz:

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

Kullanıcı denetiminiz, üstbilgi ve altbilgi gibi başka denetimler içerebilir ve ayrıca veri bağlama gibi işlevlerden yararlanabilirsiniz.


Bu cevabı bir şekilde ilk kez kaçırdım ... güzel cevap. Benim çözümüme benzer, ancak aspx yerine ascx ile. Yine de aspx'in daha iyi olacağını düşünüyorum, çünkü bir kontrol yerine tam bir sayfa sunacaktı, ama bence tam da bu.
John Bubriski

Evet, her iki çözümü de kullanabilirsiniz ... Aynı şekilde çalışırlar. Bu yaklaşımın bir yararı tutarlılıktır. Örneğin, bir kullanıcıya bir sipariş özeti gösterebilir ve aynı kontrolü yeniden kullanarak onay e-postasına tam olarak aynı şeyi ekleyebilirsiniz.
Mun

Küçük nokta, ancak ilk kod bloğunda bir StringBuilder bildirmek için bir satır eksik.
Kirschstein

9
Örnek kodun nerede bulunduğunu açıklamıyor, bu bir sayfa mı? Çünkü LoadControl bir sayfa / kontrol yöntemidir.
Shrage Smilowitz

@Mun, usercontrol'u ctrl adlı bir değişkene yüklersiniz ve kodunuzda bir daha asla referans vermezsiniz. Bunun nasıl çalışması gerekiyor?
The Muffin Man

35

MailDefinition sınıfını deneyebilirsiniz


4
Bunun basit e-postalar için iyi olduğunu, ancak karmaşık bir şey olmadığını belirtmek istiyorum. MailDefinition sınıfı, veri bağlamayı desteklemez. Gerçekten yaptığı tek şey, dizgi değiştirmeleri sunmaktır. Bununla birlikte, Üyelik Hesabı Oluşturma Sihirbazı'na da yerleştirilmiştir.
John Bubriski

4
MailDefinition sınıfı şablonlu içeriği işlemek için bir Kontrol almalıdır .. O kadar iyi değil.
Yuki

17

Kullanıcı adları, ürün adları vb. Gibi parametreleri iletmek istiyorsanız , son e-postalarınızı / HTML'lerinizi oluşturmak için açık kaynak şablon motoru NVelocity'yi kullanabilirsiniz.

NVelocity şablonuna bir örnek ( 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

Uygulamanızda MailTemplate.vm ile posta gövdesi oluşturma:

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

Sonuç posta gövdesi:

ScarletGarden tarafından hazırlanan örnek bir e-posta şablonu .

Foreach örneği:

[Tarih: 12.02.2009] Ad: Öğe 1, Değer: 09

[Tarih: 21.02.2009] Ad: Öğe 4, Değer: 52

[Tarih: 01.03.2009] Ad: Öğe 2, Değer: 21

[Tarih: 23.03.2009] Ad: 6. Öğe, Değer: 24

Şablonları düzenlemek için belki FCKEditor'ı kullanabilir ve şablonlarınızı dosyalara kaydedebilirsiniz.


7

Mail.dll e-posta bileşeni , e-posta şablonu motorunu içerir:

Söz dizimine genel bakış şu şekildedir:

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

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

</body>
</html>

Ve şablonu yükleyen, c # nesnesindeki verileri dolduran ve bir e-posta gönderen kod:

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

E-posta şablonu motoru blog yazısı hakkında daha fazla bilgi edinebilirsiniz .

Ya da Mail.dll e-posta bileşenini indirin ve deneyin.

Lütfen bunun oluşturduğum ticari bir ürün olduğunu unutmayın.


6

Esneklik ön koşullarınızdan biri ise, XSLT iyi bir seçim olabilir ve bu tamamen .NET çerçevesi tarafından desteklenir ve kullanıcının bu dosyaları düzenlemesine bile izin verebilirsiniz. Bu makale ( http://www.aspfree.com/c/a/XML/XSL-Transformations-using-ASP-NET/ ) bir başlangıç ​​için yararlı olabilir (msdn bu konuda daha fazla bilgiye sahiptir). ScarletGarden tarafından söylendiği gibi, NVelocity başka bir iyi seçimdir, ancak "yerleşik" .NET çerçeve desteği ve platformdan bağımsız olması için XSLT'yi tercih ederim.


Bunu daha önce hiç düşünmemiştim, ancak birçok başka yöntemi denedikten sonra, bunun IXmlSerializablearayüzü sınıflarıma ekleyerek harika çalıştığını gördüm. Sadece birkaç satırda sınıfımın bir e-postaya dönmesini sağlayabilirim.
cjbarth

Urgh, XSLT ile ilgili kabuslar gördüm. Muhtemelen çalıştığım en sezgisel olmayan programlama / biçimlendirme dili. Ve XSLT'nizi ilk kodladıktan 1 ay sonra başkaları için ve hatta kendiniz için bakım yapmak imkansız.
PussInBoots

5

Bunun gibi bir şey de yapabileceğinizi düşünüyorum:

Ve .aspx sayfası oluşturun ve bunu OnLoad yönteminin sonuna yerleştirin veya manuel olarak çağırın.

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

Bununla ilgili herhangi bir olası sorun olup olmadığından emin değilim, ancak işe yarayacak gibi görünüyor. Bu şekilde, yalnızca Metin değiştirmelerini destekleyen MailDefinition sınıfı yerine tam özellikli bir .aspx sayfası kullanabilirsiniz.


MailDefinition sınıfı iyi bir başlangıç ​​olsa da, biraz ilkeldir. Bu yöntem, veri bağlama ve hatta izleme gibi çok daha fazla özelliği desteklemelidir. Bununla ilgili herhangi bir düşünceniz veya potansiyel sorunlarınız var mı?
John Bubriski

Harika! Bununla ilgili herhangi bir sorunun var mı?
John Bubriski

Yani, posta şablonunda değişiklik yapmaları gerektiğinde kullanıcılarınızın .aspx dosyalarını düzenlemesine izin mi vereceksiniz? Ben buna potansiyel bir sorun derim.
Bryan

En azından, düzenleyebilecekleri diğer şablonlardan daha fazla bir risk olmadığını düşünmüyorum. Elbette, ne yaptıklarını bilirlerse, zarar verebilirler, ancak en azından bu durumda bu olası değildir. Karmaşık bir .aspx sayfası değil, daha çok yer tutucular içeren bir şablon.
John Bubriski

Uzun zaman oldu biliyorum, ama son çözümünüzü hatırlıyor musunuz? Bu özel yaklaşımı Page, en azından oluşturma için genel bir uzantı yöntemi kullanırken, a ile çalışacak şekilde elde edemedim. Bu yüzden şuna geçtim UserControl; aşağıdaki cevabıma bakın. Şimdiye kadar iyi çalışıyor gibi görünüyor ... O sırada bunu nasıl çözdüğünüzü öğrenmek isterim.
InteXX

4

Elbette bir html şablonu oluşturabilirsiniz ve ayrıca bir metin şablonu da tavsiye ederim. Şablonda, gövdenin yerleştirileceği yere [BODY] koyabilir ve ardından şablonu okuyabilir ve gövdeyi yeni içerikle değiştirebilirsiniz. E-postayı .Nets Mail Class kullanarak gönderebilirsiniz. Başlangıçta e-postayı oluşturduktan sonra, tüm alıcılara e-postanın gönderilmesi sırasında döngü yapmanız gerekir. Benim için bir cazibe gibi çalıştı.

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 öğelerini kesip File.ReadAllText (yol) ile değiştirebilirsiniz
John Sheehan

Bu iyi bir başlangıçtır, ancak yalnızca üstbilgi ve altbilgi için işlevsellik sağlar. Bu gerçekten vücudun kendisine yardımcı olmuyor.
John Bubriski

Tek yapmanız gereken gövde içeriğini HTMLBody ve TextBody Alanlarına girmek istediğiniz gövde içeriğini veya tabii ki bunları dosyalarda da saklayabilirsiniz
Josh Mein

4

Daha karmaşık e-posta şablonları için XSL dönüşümlerini kullanan bir alternatif daha: .NET uygulamalarından HTML tabanlı e-posta gönderme .


2
Bağlantı gibi. Teşekkürler! Beynim dönmeye başladı ve bunu 1 adım daha ileri götürebileceğimi fark etti ve bir XML Serileştirilebilir nesneyi veya WCF Veri Sözleşmesini doğrudan html-e-posta formatına alan bir XSLT şablonuna sahip oldum. Birdenbire, gerçek serileştirilebilir sınıflar aracılığıyla 'güçlü yazılmış' e-posta şablonlarına sahip oldum!
CodingWithSpike

2

Bunu yaparken dikkatli olun, SPAM filtreleri görünüşe göre ViewState nedeniyle ASP.net tarafından oluşturulan html'yi engelliyor gibi görünmektedir, bu nedenle bunu yapacaksanız üretilen Html'nin temiz olduğundan emin olun.

Kişisel olarak, istediğiniz sonuçları elde etmek için Asp.net MVC'yi kullanmayı düşünürdüm. veya NVelocity bu konuda oldukça iyidir


1

Bir .ASPX sayfasını bir şekilde şablon olarak kullanmak ne ideal olurdu, sonra koduma o sayfayı sunmasını söyleyin ve e-posta için döndürülen HTML'yi kullanın.

Bir ASPX sayfasına ulaşmak ve sonuçta ortaya çıkan HTML'yi almak için kolayca bir WebRequest'i oluşturabilirsiniz. Biraz daha fazla çalışmayla, muhtemelen WebRequest olmadan da yapabilirsiniz. Bir PageParser ve bir Response.Filter, sayfayı çalıştırmanıza ve çıktıyı yakalamanıza izin verir ... yine de bazı daha zarif yollar olabilir.


1

Her gün çok sayıda e-posta göndermeniz gereken projelerden birinde benzer bir gereksinimim vardı ve müşteri farklı e-posta türleri için html şablonları üzerinde tam kontrol istiyordu.

Gönderilecek çok sayıda e-posta nedeniyle, performans birincil endişe kaynağıydı.

bulduğumuz şey, farklı e-posta türleri için tüm html şablon işaretlemesini kaydettiğiniz sql sunucusundaki statik içerikti (çalışma zamanında gerçek verilerle değiştirilen [UserFirstName], [UserLastName] gibi yer tutucularla birlikte)

daha sonra bu verileri asp.net önbelleğine yükledik - bu yüzden html şablonlarını tekrar tekrar okumayız - sadece gerçekten değiştirildiklerinde

müşteriye bu şablonları bir yönetici web formu aracılığıyla değiştirmesi için bir WYSIWYG düzenleyicisi verdik. güncelleme yapıldığında asp.net önbelleğini sıfırlarız.

ve sonra e-posta günlükleri için ayrı bir tablomuz vardı - gönderilecek her e-postanın kaydedildiği yer. bu tabloda emailType, emailSent ve numberOfTries adlı alanlar vardı.

En kısa zamanda gönderilmesi gereken önemli e-posta türleri (yeni üye kaydı, unutulan şifre gibi) için her 5 dakikada bir iş çalıştırdık

daha az önemli e-posta türleri için (promosyon e-postası, haber e-postası vb.) 15 dakikada bir başka bir iş çalıştırdık

bu şekilde sunucunuzun kesintisiz e-posta göndermesini engellemezsiniz ve postaları toplu olarak işlersiniz. bir e-posta gönderildikten sonra, emailSent alanını 1 olarak ayarlayın.


Ama koleksiyonları nasıl hallettin?
Riri

1
Bunu da yaptım ve iyi çalıştı. Ayrıca, raporlar size göreyse, geçmişe dönüp gönderilen e-postaların kayıtlarını görebilirsiniz.
Mark Glorie

1

Aspx ve ascx çözümlerinin güncel bir HttpContext gerektirdiğine dikkat edin, bu nedenle zaman uyumsuz olarak (örneğin evrelerde) çok fazla çalışma yapılmadan kullanılamaz.


1

Bence kolay cevap MvcMailer. E-postalar oluşturmak için favori görünüm motorunuzu kullanmanıza olanak tanıyan NuGet paketidir. NuGet paketine buradan ve proje belgelerine bakın

Umarım yardımcı olur!


Hmm, bu cevabın bu kadar dikkat çekmemesi garip mi?
PussInBoots

1

DotLiquid başka bir seçenektir. Bir sınıf modelinden değerleri belirtirsiniz {{ user.name }}ve daha sonra çalışma zamanında o sınıftaki verileri ve biçimlendirmeyi içeren şablonu sağlarsınız ve sizin için değerleri birleştirir. Razor şablon oluşturma motorunu birçok yönden kullanmaya benzer. Döngüler gibi daha karmaşık şeyleri ve ToUpper gibi çeşitli işlevleri destekler. Güzel olan şey, bunların "güvenli" olması, böylece şablonları oluşturan kullanıcılar sisteminizi çökertemez veya jilet gibi güvenli olmayan kod yazamaz: http://dotliquidmarkup.org/try-online


0

Okumak ve bir dosyayı yazmak için ASP.NET ve ilişkili kullanıcıların iznini izin verebiliriz, kolayca standart bir HTML dosyasını kullanabilirsiniz String.Format()tutucuları ( {0}, {1:C}bunu gerçekleştirmek için, vs.).

Dosyayı yalnızca System.IOisim alanındaki sınıfları kullanarak bir dizge olarak okuyun . Bu dizeye sahip olduğunuzda, onu ilk argüman olarak String.Format()iletin ve parametreleri sağlayın.

Bu dizeyi etrafta tutun ve e-postanın gövdesi olarak kullanın ve işiniz bitti. Bunu bugün düzinelerce (kuşkusuz küçük) sitede yapıyoruz ve hiçbir sorun yaşamadık.

(A) bir seferde zilyonlarca e-posta göndermiyorsanız, (b) her bir e-postayı kişiselleştirmiyorsanız (aksi takdirde bir sürü dizeyi yiyorsunuz) ve (c ) HTML dosyasının kendisi nispeten küçüktür.


0

E-posta Mesajı IsBodyHtml = true değerini ayarlayın

E-posta içeriğinizi içeren nesnenizi alın Nesneyi seri hale getirin ve html içeriğini oluşturmak için xml / xslt kullanın.

AlternateViews yapmak istiyorsanız, jmein'in düz metin içeriği oluşturmak için yalnızca farklı bir xslt şablonu kullanmasıyla aynı şeyi yapın.

Bunun en büyük avantajlarından biri, düzeninizi değiştirmek istiyorsanız, yapmanız gereken tek şey xslt şablonunu güncellemektir.


0

SubSonic'e (www.subsonicproject.com) bakın. Kod oluşturmak için tam olarak bunu yapıyorlar - şablon standart ASPX'tir ve c # çıktısı verir. Aynı yöntem senaryonuz için yeniden kullanılabilir.


0

TemplateMachine gibi bir şablon oluşturma kitaplığı kullanırdım . bu, çoğunlukla e-posta şablonunuzu normal metinle bir araya getirmenize ve ardından değerleri gerektiği gibi enjekte etmek / değiştirmek için kuralları kullanmanıza olanak tanır. Ruby'deki ERB'ye çok benzer. Bu, sizi ASPX vb. Gibi bir şeye çok fazla bağlamadan posta içeriğinin oluşturulmasını ayırmanıza olanak tanır, ardından içerik bununla oluşturulduktan sonra e-posta gönderebilirsiniz.


0

Raj'ın cevabını beğendim. ListManager ve DNN gibi çerçeveler gibi programlar da benzer şeyler yapar ve teknik olmayan kullanıcılar tarafından kolay düzenleme yapılması gerekiyorsa, WYSIWYG editörlerinin SQL'de depolanan HTML'yi değiştirmesi çoğunlukla kolay, anlaşılır bir yoldur ve altbilgilerden bağımsız olarak başlıkları kolayca düzenleyebilir, vb. ve dinamik olarak değerler eklemek için belirteçler kullanma.

Yukarıdaki yöntemi (veya gerçekten herhangi birini) kullanıyorsanız akılda tutulması gereken bir şey, editörlerin hangi stil ve etiket türlerini eklemesine izin verdiğiniz konusunda katı ve dikkatli olmaktır. Tarayıcıların titiz olduğunu düşünüyorsanız, e-posta istemcilerinin aynı şeyi ne kadar farklı işlediğini görene kadar bekleyin ...


0

Canavar'ın cevabına benzer, ancak NVelocity yerine , şablonu bir yapılandırma dosyasından yüklediğim veya File.ReadAllText () kullanarak harici bir dosya yüklediğim ve değerleri ayarladığım " StringTemplate " kullanıyorum.

Bu bir Java projesi, ancak C # bağlantı noktası sağlam ve onu birkaç projede kullandım (sadece harici bir dosyadaki şablonu kullanarak e-posta şablonu oluşturmak için kullandım).

Alternatifler her zaman iyidir.


0

WebClient sınıfını kullanmanın basit bir yolu :

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

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

    return htmlBody;
}

Öyleyse şöyle diyelim:

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

Elbette, web sayfasının stillerini çoğu e-posta istemcisinde (Outlook gibi) göstermek için CSS'nizin hizalı olması gerekir. E-postanız dinamik içerik (örn. Müşteri Adı) gösteriyorsa, verileri doldurmak için web sitenizde QueryStrings kullanmanızı tavsiye ederim. (ör. http://www.yourwebsite.com?CustomerName=Bob )


Güzel, yine de diğer yanıtların çoğunun bunu siteye bir web isteği göndermeden, yani e-posta gövdesini sitenizde barındırmak zorunda kalmadan yaptığını düşünüyorum.
Rup

@Rup Anlaşılabilir, ancak çoğu zaman insanların e-postanın bir "Web Sürümünü" görmek istediklerini unutmayın. Bu çözüm, bu senaryo için mükemmel çalışıyor.
ROFLwTIME

0

@bardev iyi bir çözüm sunuyor, ancak maalesef her durumda ideal değil. Benimki onlardan biriydi.

VS 2013'te bir Web Sitesinde WebForms kullanıyorum (yemin ederim bir daha asla Web Sitesini kullanmayacağım - ne PITA).

Razor önerisini denedim, ancak benim bir Web sitesi olarak IDE'nin bir MVC projesinde sunduğu tüm önemli IntelliSense'i alamadım. Şablonlarım için tasarımcıyı da kullanmayı seviyorum - UserControl için mükemmel bir yer.

Yine Razor'da Nix.

Bunun yerine bu küçük çerçeveyi buldum (UserControl için @mun'a ve Güçlü Yazma için @imatoria'ya şapka ipuçları). Görebildiğim tek olası sorun noktası, .ASCX dosya adınızı sınıf adıyla uyumlu tutmaya dikkat etmeniz gerektiğidir. Eğer saparsanız, bir çalışma zamanı hatası alırsınız.

FWIW: Testlerimde en azından RenderControl () çağrısı bir Sayfa kontrolünden hoşlanmıyor, bu yüzden UserControl ile gittim.

Buraya her şeyi dahil ettiğimden oldukça eminim; bir şeyi dışarıda bırakırsam bana haber ver.

HTH

Kullanım:

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

Temel Sınıf:

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

"Fabrika" Sınıfı:

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

Şablon Sınıfı:

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 Başlığı:

<%@ 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 Altbilgisi:

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

</body>
</html>

ASCX Şablonu:

<%@ 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 Şablon Kod Dosyası:

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

Yardımcıları:

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

Sadece kullandığım kütüphaneyi karışıma atıyorum: https://github.com/lukencode/FluentEmail

E-postaları RazorLight kullanarak oluşturur , e-postaları oluşturmak için akıcı stili kullanır ve kutudan çıkan birden çok göndericiyi destekler. ASP.NET DI için de genişletme yöntemleriyle birlikte gelir. Düz metin ve HTML desteği ile kullanımı basit, küçük kurulum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.