Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将ASP.NET MVC视图作为HTML文件返回,以便在电子邮件模板中使用_C#_Asp.net_Asp.net Mvc_Asp.net Mvc 3_Email - Fatal编程技术网

C# 将ASP.NET MVC视图作为HTML文件返回,以便在电子邮件模板中使用

C# 将ASP.NET MVC视图作为HTML文件返回,以便在电子邮件模板中使用,c#,asp.net,asp.net-mvc,asp.net-mvc-3,email,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 3,Email,我正在建立一个应用程序,将发送自定义电子邮件给最终用户 我已经构建了一个HTML模板,从中可以生成电子邮件 我目前有一个模板填充了标签作为占位符的自定义内容 |Text-Placeholder| 我已将html文件作为字符串返回到我的CreateEMail方法: string html = System.IO.File.ReadAllText(Server.MapPath("~/EmailTemplates/emailTemplate.html")); 然后在自定义文本/内容中使用Strin

我正在建立一个应用程序,将发送自定义电子邮件给最终用户

我已经构建了一个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文件或直接作为字符串返回,以传递到SMTPClient实例的body属性中发送给用户


有人完成过类似的工作吗?

看看这些库:

还有ActionMailer。灵感来源于Ruby的ActionMailer

ActionMailer.Net旨在成为一种从ASP.NETMVC应用程序发送电子邮件的简单、相对轻松的方式。这个概念很简单。我们通过使用一些非常时髦的视图引擎来呈现HTML,那么为什么我们不能对电子邮件做同样的事情呢

支持很多视图引擎,当然包括Razor。并允许您将模型传递到视图中。见:

守则:

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视图生成令人惊叹的电子邮件



您可以使用此帮助程序从视图中删除Html。该方法还接受模型,视图以编程方式呈现,其输出以字符串形式返回。多多少少相同的概念:

这里是检索视图内容的位置

//The welcome email is in the Shared/Email folder
string partialViewHtml = EmailHelpers.RenderPartialToString(this.ControllerContext, "Email/Welcome", new ViewDataDictionary(modelForPartialView), new TempDataDictionary());

以上所有解决方案的问题在于它们不是线程安全的

如果要从其他线程渲染视图,该怎么办?(对于电子邮件)
在这种情况下,ControllerContext不再相关,也不再是控制器的上下文

对于这些情况,我建议以下解决方案:

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方法,也在当前控制器中调用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>
@model Phytech.PhyToWeb.Controllers.TestMailModel
@{
布局=空;
}
您好@Model.Recipient您收到了@Model.Sender关于@Model.Description的邮件

作为一个小建议,使用资源,而不是占位符。您可以创建一个资源文件,比如说在名为EMail.resx的~/Content目录中,并将您的令牌添加到其中。在视图中,您可以这样引用它们
@EMail.Name
@EMail.Address
。好处是,如果明天您需要用法语发送邮件,您可以使用所有相同的标记创建一个EMail.fr.resx,并且您已经完成了

建议副本中可能存在的重复评论请参考MVC 3中不起作用的方法,“现在更好地处理此问题”很高兴它有所帮助。我把链接和描述弄乱了一点!现在编辑答案。
@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>