题
我在 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)
...
我现在有点陷入僵局。我觉得答案是显而易见的,但我现在似乎看不到它。
解决方案 4
好了 - 所以我设法得到的东西的工作,但它是一个黑客位的,是不近,我想一个解决方案的任何地方,但它得到的东西的工作
基本上,我手动在模板加载到串然后该字符串传递给它把结果写入到所述给定的StringWriter的velocityEngine.Evaluate()方法。这样做的副作用是,在模板中的#parse指令不工作,因为它仍然无法找到这些文件。
using (StringWriter writer = new StringWriter())
{
velocityEngine.Evaluate(context, writer, templateName, template);
return writer.ToString();
}
在,因为它不使用上述TEMPLATENAME代码是无关紧要的。模板是包含已经从盘预加载整个模板的字符串。
我还是很感激任何更好的解决方案,因为我真的不喜欢这一点。
其他提示
你有没有考虑使用城堡的 NVelocityTemplateEngine?
下载从"TemplateEngine分1.1-九月29日,2009年"部分和参考的下列组件:
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();
}
其中:
- _templateEngine 是你NVelocityTemplateEngine
- 数据 是你的字典中的信息(我采用字典,使我能够访问对象的一个关键($objectKeyName)在我的模板。
- _templateContents 是的实际模板串本身。
我希望这是对你有帮助!
只是增加了,你会想要把那个放到一个静态的方法回返的一串然!
有了这个问题最近 - 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();
}
}
尝试设置file.resource.loader.path
测试是最终权威:
或者你可以使用 模板引擎组件 它是 NVelocity 的薄包装,使事情变得更容易。