我在ASP.NET MVC应用程序中使用NVelocity时遇到了一些困难。我正在使用它作为生成电子邮件的方式。
据我所知,我传递的细节都是正确的,但无法加载模板。
以下是代码:
private const string defaultTemplatePath = "Views\\EmailTemplates\\";
...
velocityEngine = new VelocityEngine();
basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, defaultTemplatePath);
ExtendedProperties properties = new ExtendedProperties();
properties.Add(RuntimeConstants.RESOURCE_LOADER, "file");
properties.Add(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, basePath);
velocityEngine.Init(properties);
basePath是正确的目录,我已将值粘贴到资源管理器中以确保它是正确的。
if (!velocityEngine.TemplateExists(name))
throw new InvalidOperationException(string.Format("Could not find a template named '{0}'", name));
Template result = velocityEngine.GetTemplate(name);
上面的'name'是上面定义为basePath的文件夹中的有效文件名。但是,TemplateExists返回false。如果我注释了条件输出并让它在GetTemplate方法调用上失败,则堆栈跟踪如下所示:
at NVelocity.Runtime.Resource.ResourceManagerImpl.LoadResource(String resourceName, ResourceType resourceType, String encoding)
at NVelocity.Runtime.Resource.ResourceManagerImpl.GetResource(String resourceName, ResourceType resourceType, String encoding)
at NVelocity.Runtime.RuntimeInstance.GetTemplate(String name, String encoding)
at NVelocity.Runtime.RuntimeInstance.GetTemplate(String name)
at NVelocity.App.VelocityEngine.GetTemplate(String name)
...
我现在陷入了一些僵局。我觉得答案很明显,但我现在似乎无法看到它。
答案 0 :(得分:5)
您是否考虑过使用Castle NVelocityTemplateEngine?
从“TemplateEngine组件1.1 - 2009年9月29日”部分下载并参考以下程序集:
using Castle.Components.Common.TemplateEngine.NVelocityTemplateEngine;
using Castle.Components.Common.TemplateEngine;
然后你可以简单地打电话:
using (var writer = new StringWriter())
{
_templateEngine.Process(data, string.Empty, writer, _templateContents);
return writer.ToString();
}
其中:
我希望这对你有所帮助!
只是要添加,你会想把它放到一个返回字符串的静态方法中!
答案 1 :(得分:3)
最近出现此问题 - 需要使用模板文件的位置初始化NVelocity。在这种情况下,mergeValues
是一种匿名类型,因此在我的模板中,我可以引用$Values.SomeItem
:
private string Merge(Object mergeValues)
{
var velocity = new VelocityEngine();
var props = new ExtendedProperties();
props.AddProperty("file.resource.loader.path", @"D:\Path\To\Templates");
velocity.Init(props);
var template = velocity.GetTemplate("MailTemplate.vm");
var context = new VelocityContext();
context.Put("Values", mergeValues);
using (var writer = new StringWriter())
{
template.Merge(context, writer);
return writer.ToString();
}
}
答案 2 :(得分:2)
尝试设置file.resource.loader.path
答案 3 :(得分:1)
好的 - 所以我设法让事情变得有效,但它有点像黑客并且不是我想要的任何解决方案,但它有一些工作。
基本上,我手动将模板加载到字符串中,然后将该字符串传递给velocityEngine.Evaluate()方法,该方法将结果写入给定的StringWriter。这样做的副作用是模板中的#parse指令不起作用,因为它仍然无法找到文件。
using (StringWriter writer = new StringWriter())
{
velocityEngine.Evaluate(context, writer, templateName, template);
return writer.ToString();
}
在上面的代码中,templateName是不相关的,因为它没有被使用。 template是包含从磁盘预加载的整个模板的字符串。
我仍然感谢任何更好的解决方案,因为我真的不喜欢这个。
答案 4 :(得分:0)
测试是最终的权威:
或者您可以使用TemplateEngine component这是一个围绕NVelocity的薄包装,使事情变得更容易。