Adding a dictionary with values like this:

Dictionary<string, string> CustomArray = new Dictionary<string, string>();
CustomArray.Add("customValue1", "mydata");
this.velocityContext.Put("array", CustomArray);

Using the template engine like this:

Velocity.Init();  
string template = FileExtension.GetFileText(templateFilePath);
var sb = new StringBuilder();

using(StringWriter sw = new StringWriter(sb))
{
    using(StringReader sr = new StringReader(template))
    {
        Velocity.Evaluate(
           this.velocityContext,
           sw,
           "test template",
           sr);
    }
 }
 return sb.ToString();

Accessed in template like this:

$array.Get_Item('customValue1')

$array.Get_Item('customValue2')

customValue1 is retrieved fine, but customValue2 is throwing an KeyNotFoundException because the key does not exists in the dictionary. How can I still generate the template without removing the line that throws KeyNotFoundException?

I've looked at the Apache Velocity guideline but I'm not sure how to append this (https://velocity.apache.org/tools/devel/creatingtools.html#Be_Robust)

有帮助吗?

解决方案

This looks like a defect with NVelocity's handling of .NET's Dictionary<K,V>. Because of NVelocity's origins in Velocity before Java supported generics and because NVelocity is an old codebase, I tried with a non-generic Hashtable and it works as expected. Since the map isn't typed in the NVelocity template, it should be a drop in change to switch classes to workaround this defect.

Feel free to log the defect, but without a pull request it is very unlikely to be fixed.

VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.Init();

Hashtable dict = new Hashtable();
dict.Add("customValue1", "mydata");

VelocityContext context = new VelocityContext();
context.Put("dict", dict);

using (StringWriter sw = new StringWriter())
{
    velocityEngine.Evaluate(context, sw, "",
        "$dict.get_Item('customValue1')\r\n" +
        "$dict.get_Item('customValue2')\r\n" +
        "$!dict.get_Item('customValue2')"
    );

    Assert.AreEqual(
        "mydata\r\n" +
        "$dict.get_Item('customValue2')\r\n" +
        "",
        sw.ToString());
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top