.net - 创建一个实现 ILiquidizable 的 DataRow 类

标签 .net asp.net liquid

我正在尝试使用 Dot Liquid这是最酷的 c# 模板引擎之一。 Dot Liquid 使用一种方法来确保使用模板安全。 Here is the explanation page.

这是来自它的 wiki 的解释:

DotLiquid, by default, only accepts a limited number of types as parameters to the Render method - including the .NET primitive types(int, float, string, etc.), and some collection types including IDictionary, IList and IIndexable (a custom DotLiquid interface).

If it supported arbitrary types, then it could result in properties or methods being unintentionally exposed to template authors. To prevent this, DotLiquid uses Drop objects. Drops use an opt-in approach to exposing object data.

The Drop class is just one implementation of ILiquidizable, and the simplest way to expose your objects to DotLiquid templates is to implement ILiquidizable directly

维基示例代码:

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class UserDrop : Drop
{
    private readonly User _user;

    public string Name
    {
        get { return _user.Name; }
    }

    public UserDrop(User user)
    {
        _user = user;
    }
}

Template template = Template.Parse("Name: {{ user.name }}; Email: {{ user.email }};");
string result = template.Render(Hash.FromAnonymousObject(new
{
    user = new UserDrop(new User
    {
        Name = "Tim",
        Email = "me@mydomain.com"
    })
}));

所以当我将 DataRow 传递给 liquid 时,liquid 不会让我显示它的内容并告诉我:

'System.Data.DataRow' is invalid because it is neither a built-in type nor implements ILiquidizable

是否有任何解决方案来传递实现 ILiquidizable 的 DataRow 对象? 谢谢

最佳答案

正如 marc_s 所指出的,您需要将 DataRow 对象转换为您自己的类实例,或者至少用您自己的类实例包装它。我建议像这样包装它:

internal class DataRowDrop : Drop
{
    private readonly DataRow _dataRow;

    public DataRowDrop(DataRow dataRow)
    {
        _dataRow = dataRow;    
    }

    public override object BeforeMethod(string method)
    {
        if (_dataRow.Table.Columns.Contains(method))
            return _dataRow[method];
        return null;
    }
}

示例用法为:

[Test]
public void TestDataRowDrop()
{
    DataTable dataTable = new DataTable();
    dataTable.Columns.Add("Column1");
    dataTable.Columns.Add("Column2");

    DataRow dataRow = dataTable.NewRow();
    dataRow["Column1"] = "Hello";
    dataRow["Column2"] = "World";

    Template tpl = Template.Parse(" {{ row.column1 }} ");
    Assert.AreEqual(" Hello ", tpl.Render(Hash.FromAnonymousObject(new
    {
        row = new DataRowDrop(dataRow)
    })));
}

我还在 unit tests for DotLiquid drops 中添加了这个示例 drop 类和相应的单元测试。 .

关于.net - 创建一个实现 ILiquidizable 的 DataRow 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424341/

相关文章:

c# - 该方法或操作未实现。在 C# 中停止 IIS 网站时

ruby - Liquid 模板 - 按名称访问成员

Jekyll strip_html 但允许某些 HTML 标签

jekyll - 从液体数组中获取下一个和上一个元素

c# - List.AddRange 内联声明

javascript - 使按钮显示为链接

c# - 从 F# 使用 UWP 应用服务

c# - 如何在 asp.net 中的卸载事件之前分配值

c# - 将文本框值更改 +/-10

c# - 添加新行时防止滚动到 datagridview 中的选定行