0

I have being tasked with setting up a way where an admin user can easily pick articles to send out to a list of subscribers. The below image is what i'm trying to create but my problem is how get the view sent in an email. I have it created as a static template and as a razor template. I tried to use RazorEngine and Razorlight but can't figure them out.

enter image description here

Alot of the questions i have seen on this only adds one item to a email. e.g here and here. I am using MailKit to send emails but for the life of me i cant figure how to get an email body like above. My code looks like this

   var mimeMessage = new MimeMessage();
            mimeMessage.From.Add(new MailboxAddress("email", "intranet@domain.com"));
            foreach (var item in contacts)
            {
                mimeMessage.To.Add(new MailboxAddress(ToAdressTitle, string.Join(",", item.Email.ToString())));
            }
            mimeMessage.Subject = Subject;
            var builder = new BodyBuilder();
            foreach (var item in post)
            {
                // Set the plain-text version of the message text
                builder.TextBody = item.Intro;
                 var ContentId = MimeUtils.GenerateMessageId();
                // Set the html version of the message text
                builder.HtmlBody = string.Format(item.Intro,@"<img src=""cid:{0}"">", item.FeaturedImage);
                // Now we just need to set the message body and we're done
                mimeMessage.Body = builder.ToMessageBody();
            }

Can i get my desired layout like this?

MOSCODE
  • 272
  • 7
  • 16
  • So what is the exact problem? We cannot help you to "figure out" Razor, you will need a tutorial or book. We could help you figure out a specific problem, if you post one though. The approach without Razor seems to be a straightforward loop. Again, we cannot help you "figure it out". we can only help you with a *specific* question. What exactly are you stuck on? – nvoigt Aug 16 '18 at 09:56
  • I know Razor i didn't ask to figure out razor. I asked can i get my desired layout to send the newsletter. I can create the layout in razor that's easy but i cant get it to send in an email. Email can only plain or html – MOSCODE Aug 16 '18 at 10:05
  • I'm not sure I understand where the problem is. I thought you *wanted* to send HTML? Your list looks like it would be HTML. – nvoigt Aug 16 '18 at 10:07
  • OK i can create my desired layout in a razor view but what i can't figure out is how to send the view in a HTML email. – MOSCODE Aug 16 '18 at 10:13
  • Simplistically, you need to render the Razor view to a string and then send that as your HTML body of your email. However, rendering a Razor view to a string is non-trivial and beyond the scope of Stack Overflow. You'll need to do your own research on that one. A cursory search returned many examples online. Personally, I prefer to go lighter-weight with my emails and just use Handlebars.Net on basic `*.html` files (actually generated via MJML). – Chris Pratt Aug 16 '18 at 13:43

1 Answers1

1

After a long time searching i cam across this answer which enabled my to get the answer i was looking for. First i add this code to my constructor

 public class PostsController : Controller
{
        private ICompositeViewEngine _viewEngine;

       public PostsController(ICompositeViewEngine viewEngine)
       {
           _viewEngine = viewEngine;
       }

 } 

To render the view as a string i use this function

       private async Task<string> RenderViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = ControllerContext.ActionDescriptor.ActionName;

        ViewData.Model = model;

        using (var writer = new StringWriter())
        {
            ViewEngineResult viewResult =
                _viewEngine.FindView(ControllerContext, viewName, false);

            ViewContext viewContext = new ViewContext(
                ControllerContext,
                viewResult.View,
                ViewData,
                TempData,
                writer,
                new HtmlHelperOptions()
            );

            await viewResult.View.RenderAsync(viewContext);

            return writer.GetStringBuilder().ToString();
        }
    }

and i call it like this var renderedView = await RenderViewToString("NameOfView", Model); The model is the data i want to display.

var mimeMessage = new MimeMessage();
        mimeMessage.From.Add(new MailboxAddress("email", "intranet@domain.com"));
        foreach (var item in contacts)
        {
            mimeMessage.To.Add(new MailboxAddress(ToAdressTitle, string.Join(",", item.Email.ToString())));
        }
        mimeMessage.Subject = Subject;
        var builder = new BodyBuilder();                                             
            // Set the html version of the message text
            builder.HtmlBody = renderedView;
            // Now we just need to set the message body and we're done
            mimeMessage.Body = builder.ToMessageBody();

This enables me to get the desired view.

MOSCODE
  • 272
  • 7
  • 16