强类型Razor视图作为电子邮件模板引擎

时间:2012-09-29 22:06:38

标签: asp.net-mvc-3 razor mocking asp.net-mvc-4

我知道有几个类似的问题可以解决这个问题,但我对答案不满意。

我想要的是充分利用Razor View引擎,该引擎可以使用带有布局页面和部分视图的强类型视图。我想在我的视图顶部声明模型,然后传入该模型。很简单!没有动态模型需要在将它们传递到视图之前显式构造。 编辑:我想在可以构建电子邮件正文的类库中执行Web应用程序 之外的。这里真正的问题是使用不是网络应用程序的Razor View引擎。

这背后的想法是,如果我有一个User对象,其上有20个属性,我的第一个版本的欢迎电子邮件只使用了名称,但后来我想编辑模板以使用他们的{{1 }},CityState地址,然后我希望能够更新Razor视图,而无需添加代码并重新编译和重新部署。

我看到 RazorEngine ,我喜欢这个想法和简单,但一切都是动态的。我的问题是,我将从数据库中提取数据作为模型。通过将事物推入动态类型,我不会在View上获得所有属性。

我也看到了 MvcMailer ,这在理论上也很不错,但它遇到了同样的问题,即传递给视图的所有数据模型都是动态的而不是强类型的。

我已经开始构建我自己的版本,这将需要几个Web命名空间,如System.Web.Mvc,System.Web.Razor和System.Web.WebPages - 我很好。问题是缺少HttpContext和ControllerContext以及RouteData ....我正在尝试模拟/存根所以。我目前正在尝试研究DisplayModes并弄清楚如何在真实的Web环境之外模拟它们。

有更好的方法吗?如果您要建议前面提到的两个框架中的一个,请注意我的问题,如果有解决方法,请告诉我。

编辑2:在使用RazorEngine玩了一下之后,强类型模型不一定像我想象的那么多。我现在想要的是能够使用布局页面和部分视图。我可以通过替换字符串占位符来解决这个问题,但可能效率不高且不够灵活。

4 个答案:

答案 0 :(得分:4)

假设您正尝试在控制器的动作方法中实现此目的,这是一种简单的方法。

此方法将为您提供强类型视图的输出:

public static string RenderViewToString(this Controller controller, string viewName, object model)
{
    controller.ViewData.Model = model;
    try
    {
        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, null);
            ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View);

            return sw.ToString();
        }
    }
    catch(Exception ex)
    {
        return ex.ToString();
    }
}

然后在控制器方法中,您需要做的就是使用视图和模型的名称调用此方法。

public ActionResult Mail()
{
    // whatever you use to get your User object
    var model = new User();

    var output = this.RenderViewToString("~/Views/User/Email.cshtml", model)
}

这将允许您模拟强类型视图的呈现,包括其关联的布局,并将输出收集为字符串,然后您可以使用该字符串通过电子邮件发送。

答案 1 :(得分:0)

答案是,传入的对象是否是动态的似乎并不重要。我可以传递我的强类型对象,它将被接受,而不需要使其动态或重建动态对象。

我的初步测试表明这应该没问题并且运作良好。

答案 2 :(得分:0)

试用Actionmailer.net:https://bitbucket.org/swaj/actionmailer.net/wiki/Home

我一直在成功使用它。

答案 3 :(得分:0)

结帐RazorMachine。它就像RazorEngine,但适用于布局。