I would like to set email related properties on my razor template base class which can be used to send an email with the rendered template as the body.
How can I get a reference to the compiled template?
No you can't and that's by design. But you probably want to do the following instead:
public class EmailDataHolder {
public string Destination { get; set; }
public string Subject { get; set; }
}
// In the custom TemplateBase class:
public class EmailTemplateBase<T> : TemplateBase<T>
{
public EmailDataHolder EmailProperties { get { return Viewbag.DataHolder; } }
// Or for even simpler templates
//public string Subject { get { return Viewbag.DataHolder.Subject; }; set { Viewbag.DataHolder.Subject = value; } }
}
// Your code
public static Task SendEmailAsync<T>(string templateName, string destination, T model)
{
var holder = new EmailDataHolder();
dynamic viewbag = new DynamicViewBag();
viewbag.DataHolder = holder;
holder.Destination = destination;
var body = Engine.Razor.Run(templateName, typeof(T), model, (DynamicViewBag)viewbag);
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress(holder.Destination));
msg.Subject = holder.Subject;
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html));
SmtpClient smtpClient = new SmtpClient();
return smtpClient.SendMailAsync(msg);
}
If you want to use @model
you want to configure RazorEngine to use this custom TemplateBase
implementation:
config.BaseTemplateType = typeof(EmailTemplateBase<>);
and then you can use it like this:
@inherits EmailTemplateBase<HelloWorldModel>
@{
Layout = "CI";
EmailProperties.Subject = "Hello World";
// with the simpler version
//Subject = "Hello World";
}
Hello @Model.Name,<br/>
this is a test email...
While this doesn't really give you the reference to the compiled template it allows you to save data within the template and use it later.