我知道有几个类似的问题可以解决这个问题,但我对答案不满意。
我想要的是充分利用Razor View引擎,该引擎可以使用带有布局页面和部分视图的强类型视图。我想在我的视图顶部声明模型,然后传入该模型。很简单!没有动态模型需要在将它们传递到视图之前显式构造。 编辑:我想在可以构建电子邮件正文的类库中执行Web应用程序 之外的。这里真正的问题是使用不是网络应用程序的Razor View引擎。
这背后的想法是,如果我有一个User
对象,其上有20个属性,我的第一个版本的欢迎电子邮件只使用了名称,但后来我想编辑模板以使用他们的{{1 }},City
或State
地址,然后我希望能够更新Razor视图,而无需添加代码并重新编译和重新部署。
我看到 RazorEngine ,我喜欢这个想法和简单,但一切都是动态的。我的问题是,我将从数据库中提取数据作为模型。通过将事物推入动态类型,我不会在View上获得所有属性。
我也看到了 MvcMailer ,这在理论上也很不错,但它遇到了同样的问题,即传递给视图的所有数据模型都是动态的而不是强类型的。
我已经开始构建我自己的版本,这将需要几个Web命名空间,如System.Web.Mvc,System.Web.Razor和System.Web.WebPages - 我很好。问题是缺少HttpContext和ControllerContext以及RouteData ....我正在尝试模拟/存根所以。我目前正在尝试研究DisplayModes并弄清楚如何在真实的Web环境之外模拟它们。
有更好的方法吗?如果您要建议前面提到的两个框架中的一个,请注意我的问题,如果有解决方法,请告诉我。
编辑2:在使用RazorEngine玩了一下之后,强类型模型不一定像我想象的那么多。我现在想要的是能够使用布局页面和部分视图。我可以通过替换字符串占位符来解决这个问题,但可能效率不高且不够灵活。
答案 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,但适用于布局。