Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Razor outside of web project

I would like to generate emails using the Razor view engine.

From what I've read, I can use these OS projects to do that from my website:

  • Postal
  • ActionMailer.Net
  • MvcMailer

However, all these use example where the user submits a form and an email is sent from the contoller. When creating the email a ControllerContext seems to be required. I am hoping to do the generating within my "Service" layer at periodic intervals, so I doubt I have access to the ControllerContext.

Is this doable?

like image 677
Cloud SME Avatar asked Mar 30 '11 06:03

Cloud SME


People also ask

Why are Razor pages better than MVC?

From the docs, "Razor Pages can make coding page-focused scenarios easier and more productive than using controllers and views." If your ASP.NET MVC app makes heavy use of views, you may want to consider migrating from actions and views to Razor Pages.

Is Razor a front end framework?

So, to answer your question, Razor is a front-end technology that executes on the server-side runtime. It's only purpose is to generate the UI, which is the concern of the front-end. Show activity on this post. Razor is for writing dynamic html page which is front end and c# is for writing backend logic.

Which type of content is observed on a Razor Web page?

In a web page that uses the Razor syntax, there are two kinds of content: client content and server code. Client content is the stuff you're used to in web pages: HTML markup (elements), style information such as CSS, maybe some client script such as JavaScript, and plain text.

Is Razor a programming language?

Razor is not a programming language. It's a server side markup language.


1 Answers

Check this out. I'm using it with templates as embedded resources like this (but can be modified to locate templates anywhere):

public static class MailSender
{
    static MailSender()
    {
        CompilerServiceFactory = new DefaultCompilerServiceFactory();
        TemplateService = new TemplateService(CompilerServiceFactory.CreateCompilerService(), typeof(MailTemplate<>));
    }

    private static ICompilerServiceFactory CompilerServiceFactory { get; set; }
    private static TemplateService TemplateService { get; set; }

    private static ITemplate<T> GetTemplate<T>(T model)
    {
        string path = typeof(T).FullName;

        var assembly = Assembly.GetExecutingAssembly();

        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
        {
            if (stream == null)
                throw new FileNotFoundException("Mail template not found");

            using (var reader = new StreamReader(stream))
            {
                string source = reader.ReadToEnd();

                return TemplateService.GetTemplate<T>(source, model);
            }
        }
    }

    public static void Send<T>(string to, T model)
    {
        Send(new string[] { to }, new string[] { }, new string[] { }, model);
    }
    public static void Send<T>(string to, string cc, string bcc, T model)
    {
        Send(new string[] { to }, new string[] { cc }, new string[] { bcc }, model);
    }
    public static void Send<T>(string[] to, string[] cc, string[] bcc, T model)
    {
        var template = (MailTemplate<T>)GetTemplate<T>(model);

        template.Execute();

        Trace.WriteLine(string.Format("To: {0} Subject: {1}{3}Body: {2}", string.Join(",", to), template.Subject, template.Result, Environment.NewLine), "Mail");
#if !LOCAL
        using (var message = new MailMessage())
        using (var client = new SmtpClient())
        {
            if (!string.IsNullOrWhiteSpace(template.From))
                message.From = new MailAddress(template.From);

            message.To.Add(string.Join(",", to));

            if (cc != null && cc.Length > 0)
                message.CC.Add(string.Join(",", cc));

            if (bcc != null && bcc.Length > 0)
                message.Bcc.Add(string.Join(",", bcc));

            message.Subject = template.Subject;

            message.Body = template.Result;
            message.IsBodyHtml = true;

            client.Send(message);
        }
#endif
    }
}

public abstract class MailTemplate<TModel> : TemplateBase<TModel>
{
    public string From { get; set; }
    public string Subject { get; set; }
}

model:

public class Contact
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Text { get; set; }
}

template:

@inherits Feedback.Lib.Mail.MailTemplate<Feedback.Lib.Mail.Templates.Contact>
@{
    From = string.Format("{0} <{1}>", Model.Name, Model.Email);
    Subject = "Contact request - " + From; 
}

@Model.Text

I have for each template it's own model, so its easy to locate them via class name. Also I was unable to make intellisense work.

like image 188
Lukáš Novotný Avatar answered Sep 21 '22 13:09

Lukáš Novotný