【问题标题】:NVelocity ASP.NET ExamplesNVelocity ASP.NET 示例
【发布时间】:2010-03-17 11:10:47
【问题描述】:

我希望在我的 ASP.NET MVC 应用程序中使用 NVelocity,而不是作为视图引擎,仅用于呈现一些电子邮件模板。

但是,我这辈子都无法让它发挥作用。我已经从城堡项目中下载了它,并按照http://www.castleproject.org/others/nvelocity/usingit.html#step1的示例进行操作

无论我尝试什么,我似乎都无法加载位于我网站中的模板。该示例建议使用绝对路径,但我尝试过无济于事:

Template t = engine.GetTemplate("/Templates/TestEmail.vm");

所以请谁能给我两个例子。一是加载位于网站目录中的模板,二是解析字符串变量(因为我的模板可能会存储在数据库中)。

非常感谢 本

【问题讨论】:

  • 不确定这是否会有所帮助,但这里有一篇不错的文章:codeproject.com/KB/aspnet/nvelocityaspnet.aspx
  • @rohancragg - 是的,我看到了这篇文章。虽然它已经很老了,而且自从该项目被 Castle 接管以来,用于处理模板的方法似乎已经发生了变化。还是谢谢

标签: asp.net nvelocity


【解决方案1】:

我在过去的一个项目中使用过这个类:

public interface ITemplateRepository
{
    string RenderTemplate(string templateName, IDictionary<string, object> data);
    string RenderTemplate(string masterPage, string templateName, IDictionary<string, object> data);
}

public class NVelocityTemplateRepository : ITemplateRepository
{
    private readonly string _templatesPath;

    public NVelocityTemplateRepository(string templatesPath)
    {
        _templatesPath = templatesPath;
    }

    public string RenderTemplate(string templateName, IDictionary<string, object> data)
    {
        return RenderTemplate(null, templateName, data);
    }

    public string RenderTemplate(string masterPage, string templateName, IDictionary<string, object> data)
    {
        if (string.IsNullOrEmpty(templateName))
        {
            throw new ArgumentException("The \"templateName\" parameter must be specified", "templateName");
        }

        var name = !string.IsNullOrEmpty(masterPage)
            ? masterPage : templateName;

        var engine = new VelocityEngine();
        var props = new ExtendedProperties();
        props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, _templatesPath);
        engine.Init(props);
        var template = engine.GetTemplate(name);
        template.Encoding = Encoding.UTF8.BodyName;
        var context = new VelocityContext();

        var templateData = data ?? new Dictionary<string, object>();
        foreach (var key in templateData.Keys)
        {
            context.Put(key, templateData[key]);
        }

        if (!string.IsNullOrEmpty(masterPage))
        {
            context.Put("childContent", templateName);
        }

        using (var writer = new StringWriter())
        {
            engine.MergeTemplate(name, context, writer);
            return writer.GetStringBuilder().ToString();
        }
    }
}

为了实例化NVelocityTemplateRepository 类,您需要提供模板根目录所在的绝对路径。然后您使用相对路径来引用您的 vm 文件。

【讨论】:

  • @Darin,我尝试了您的示例,但在尝试加载模板文件时仍然出现相同的错误。也许我错误地传递了我的路径。有问题的模板是 ~/Content/Templates/TestEmail.vm ,我的代码如下: var templatesPath = VirtualPathUtility.ToAbsolute("~/Content/templates"); ITemplateService templateService = new NVelocityTemplateService(templatesPath); var objs = new Dictionary(); return templateService.RenderTemplate("TestEmail.vm", objs);
  • VirtualPathUtility 不返回绝对路径。您需要传递一个绝对路径,例如c:\mytemplates。试试这个:Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"Content\templates").
  • 我更改为 Server.MapPath 以获取服务器上的物理目录。现在是一种享受。谢谢。
【解决方案2】:

我还添加了以下方法来处理字符串而不是模板文件(例如,如果从数据库中检索模板内容):

        public string RenderTemplateContent(string templateContent, IDictionary<string, object> data)
    {
        if (string.IsNullOrEmpty(templateContent))
            throw new ArgumentException("Template content cannot be null", "templateContent");

        var engine = new VelocityEngine();
        engine.Init();

        var context = GetContext(data);

        using (var writer = new StringWriter()) {
            engine.Evaluate(context, writer, "", templateContent);
            return writer.GetStringBuilder().ToString();
        }
    }

并使用 StructureMap 来初始化服务:

            ForRequestedType<ITemplateService>()
            .TheDefault.Is.ConstructedBy(()=> 
                new NVelocityTemplateService(HttpContext.Current.Server.MapPath("~/Content/Templates/")));

【讨论】:

    【解决方案3】:

    您可能会发现TemplateEngine component 很有用。

    它是对具有 NVelocity 实现的模板引擎的抽象,类似于 Darin's answer,但它的性能应该稍微好一些,因为它使用 VelocityEngine 的单个实例(而不是每次渲染初始化一个实例)并且具有可选的缓存。它还有一些其他功能,例如日志记录、NVelocity 属性覆盖和从程序集资源加载模板。

    【讨论】:

      猜你喜欢
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多