Сделайте класс DataRow, который реализует ILiquidizable - PullRequest
3 голосов
/ 13 декабря 2010

Я пытаюсь использовать Dot Liquid , который является одним из самых крутых шаблонизаторов для c #. Dot Liquid использует способ, чтобы сделать использование шаблонов безопасным. Вот страница объяснения.

Вот объяснение из его вики:

DotLiquid, по умолчанию, принимает только ограниченное количество типов в качестве параметров к методу рендеринга - включая Примитивные типы .NET (int, float, строка и т. д.), а также некоторые коллекции типы, включая IDictionary, IList и IIndexable (пользовательский DotLiquid интерфейс).

Если он поддерживает произвольные типы, то это может привести к свойствам или методы непреднамеренного воздействия авторам шаблонов. Чтобы предотвратить это, DotLiquid использует Drop-объекты. Капли используют opt-in подход к экспонированию объекта данные.

Класс 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"
    })
}));

Поэтому, когда я передаю DataRow в жидкость, жидкость не позволяет мне показывать ее содержимое и говорит мне, что:

'System.Data.DataRow' недействителен потому что это не встроенный тип ни не реализует ILiquidizable

Есть ли решения для передачи объекта DataRow, который также реализует ILiquidizable? Спасибо

1 Ответ

5 голосов
/ 13 декабря 2010

Как указано в 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)
    })));
}

Я также добавил этот пример класса отбрасывания и соответствующий модульный тест в модульные тесты для капель DotLiquid .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...