EBA*_*BAG 3 .net asp.net liquid
我正在尝试使用Dot Liquid,这是c#最酷的模板引擎之一.Dot Liquid使用一种方法来使模板安全.这是解释页面.
这是来自wiki的解释:
默认情况下,DotLiquid只接受有限数量的类型作为Render方法的参数 - 包括.NET基元类型(int,float,string等),以及一些集合类型,包括IDictionary,IList和IIndexable(自定义DotLiquid)接口).
如果它支持任意类型,则可能导致无意中向模板作者公开属性或方法.为了防止这种情况,DotLiquid使用Drop对象.丢弃使用选择加入方法来暴露对象数据.
Drop类只是ILiquidizable的一个实现,将对象公开给DotLiquid模板的最简单方法是直接实现ILiquidizable
Wiki示例代码:
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"
})
}));
Run Code Online (Sandbox Code Playgroud)
因此,当我将DataRow传递给液体时,液体不会让我显示它的内容,并告诉我:
'System.Data.DataRow'无效,因为它既不是内置类型也不实现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;
}
}
Run Code Online (Sandbox Code Playgroud)
示例用法是:
[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)
})));
}
Run Code Online (Sandbox Code Playgroud)
我还将这个示例drop class和相应的单元测试添加到DotLiquid drop的单元测试中.