Вернуть ASP.NET MVC View в виде HTML-файла для использования в шаблоне электронной почты. - PullRequest
5 голосов
/ 13 января 2012

Я создаю приложение, которое будет отправлять пользовательские электронные письма конечным пользователям.

Я создал шаблон HTML, из которого будут создаваться электронные письма.

В настоящее время шаблон заполнен тегами в качестве заполнителей для пользовательского содержимого ...

|Text-Placeholder|

Я возвращаю html-файл в виде строки в мой метод CreateEMail:

string html = System.IO.File.ReadAllText(Server.MapPath("~/EmailTemplates/emailTemplate.html"));

И затем использование String.Replace для замены в пользовательском тексте / содержимом

html = html.Replace("|Name-Placeholder|", username);

Мне любопытно, есть ли метод, который позволил бы мне создать шаблон как RazorView, строго типизированный как ViewModel, который будет моделировать пользовательский текст / контент и возвращать представление в виде файла HTML или непосредственно в виде строки передать в свойство body моего экземпляра SMTPClient для отправки пользователю?

Кто-нибудь достиг такого или подобного?

Ответы [ 4 ]

10 голосов
/ 13 января 2012

Посмотрите на эти библиотеки:

Есть ActionMailer. Вдохновлен Руби ActionMailer.

ActionMailer.Net стремится быть простым и относительно безболезненным способом отправки электронной почты из приложения ASP.NET MVC. Концепция довольно проста. Мы визуализируем HTML, используя довольно привлекательные механизмы просмотра, так почему же мы не можем сделать то же самое для электронной почты?

http://nuget.org/packages/ActionMailer

Я думаю, что поддерживает множество движков просмотра, в том числе Razor. И позволяет передавать модель в вид. Увидеть: https://bitbucket.org/swaj/actionmailer.net/wiki/Home

код:

public class MailController : MailerBase
{
    public EmailResult VerificationEmail(User model)
    {
        To.Add(model.EmailAddress);
        From = "no-reply@mycoolsite.com";
        Subject = "Welcome to My Cool Site!";
        return Email("VerificationEmail", model);
    }
}

Вид:

@using ActionMailer.Net
@model User
@{
    Layout = null;
}
Welcome to My Cool Site, @Model.FirstName. We need you to verify your email.
Click this nifty link to get verified!

Существует также другая библиотека:

MvcMailer позволяет вам использовать MVC Views для создания потрясающих электронных писем

http://nuget.org/packages/MvcMailer
https://github.com/smsohan/MvcMailer

0 голосов
/ 26 декабря 2013

в качестве небольшого предложения, вместо заполнителей, используйте ресурсы.вы создаете файл ресурсов, скажем, в каталоге ~ / Content с именем EMail.resx и добавляете в него свои токены.в представлении вы можете ссылаться на них, как это @EMail.Name и @EMail.Address.Преимущество состоит в том, что если завтра вам нужно будет отправить почту на французском языке, вы создадите EMail.fr.resx с теми же токенами, и все готово

0 голосов
/ 20 ноября 2013

проблема со всеми вышеупомянутыми решениями заключается в том, что они не безопасны для потоков !.

что если вы хотите визуализировать вид из другого потока? (для электронной почты)
в этом случае ControllerContext больше не относится ни к этому Controller

для этих случаев я предлагаю следующее решение:

ThreadPool.QueueUserWorkItem(_ =>
{
    var model = new TestMailModel() { Sender = "yakirmanor", Recipient = "yakirmanor@notrealmail.com", Description = "some desc" };
    string test1 = ControllerExtensions.RenderView("Mail", "TestMail", model);
    string test2 = this.RenderView("TestMail", model);
    string test3 = this.RenderView(model);
    // now send the mail
    //MailHelper.SendEmail("yakirmanor@notrealmail.com", "subject", test1, "username", "password");
});

здесь вы можете видеть, как я вызываю метод TestMail в контроллере Mail, а также TestMail в текущем контроллере.
создать расширения

public static class ControllerExtensions
{
    public static string RenderView(this Controller controller, object model)
    {
        string viewName = controller.ControllerContext.RouteData.Values["action"].ToString();
        string controllerName = controller.ControllerContext.RouteData.Values["controller"].ToString();
        return RenderView(controllerName, viewName, model);
    }

    public static string RenderView(this Controller controller, string viewName, object model)
    {
        string controllerName = controller.ControllerContext.RouteData.Values["controller"].ToString();
        return RenderView(controllerName, viewName, model);
    }

    public static string RenderView(string controllerName, string viewName, object viewData)
    {
        //Create memory writer
        var writer = new StringWriter();

        var routeData = new RouteData();
        routeData.Values.Add("controller", controllerName);

        //Create fake http context to render the view
        var fakeRequest = new HttpRequest(null, "http://tempuri.org", null);
        var fakeResponse = new HttpResponse(null);
        var fakeContext = new HttpContext(fakeRequest, fakeResponse);
        var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeContext), routeData, new FakeController());

        var razorViewEngine = new RazorViewEngine();
        var razorViewResult = razorViewEngine.FindView(fakeControllerContext,viewName,"",false);

        var viewContext = new ViewContext(fakeControllerContext, razorViewResult.View, new ViewDataDictionary(viewData), new TempDataDictionary(), writer);
        razorViewResult.View.Render(viewContext, writer);

        return writer.ToString();
    }
}

чтобы использовать код, необходимый для добавления вашей модели и поддельного контроллера

public class TestMailModel
{
    public string Sender { get; set; }
    public string Recipient { get; set; }
    public string Description { get; set; }
}

class FakeController : ControllerBase
{
    protected override void ExecuteCore() { }
}

вид может выглядеть так:

@model Phytech.PhyToWeb.Controllers.TestMailModel
@{
Layout = null;
}
<table cellpadding="8" cellspacing="0" style="width: 100%!important; background: #ffffff; margin: 0; padding: 0" border="0">
    <tbody><tr><td valign="top">
    Hi @Model.Recipient youve got mail from @Model.Sender about @Model.Description
    </td></tr></tbody>
</table>
0 голосов
/ 14 января 2012

вы можете использовать этот помощник, чтобы убрать HTML из вида.Метод принимает также модель, представление визуализируется программно, а его выходные данные возвращаются в виде строки.Больше или меньше той же концепции LoadControl в Asp.net :

public static string RenderPartialToString(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData)
{
    var viewEngineResult = ViewEngines.Engines.FindPartialView(context, partialViewName);

    if (viewEngineResult.View != null)
    {
        var stringBuilder = new StringBuilder();
        using (var stringWriter = new StringWriter(stringBuilder))
        {
            using (var output = new HtmlTextWriter(stringWriter))
            {
                ViewContext viewContext = new ViewContext(context, viewEngineResult.View, viewData, tempData, output);
                viewEngineResult.View.Render(viewContext, output);
            }
        }

        return stringBuilder.ToString();
    }

    //return string.Empty;
    throw new FileNotFoundException("The view cannot be found", partialViewName);
}

Вот где извлекается содержимое представления

//The welcome email is in the Shared/Email folder
string partialViewHtml = EmailHelpers.RenderPartialToString(this.ControllerContext, "Email/Welcome", new ViewDataDictionary(modelForPartialView), new TempDataDictionary());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...