Хелперы ASP.NET RAZOR MVC5 для использования с using

300
29 июня 2017, 01:08

В ASP.NET RAZOR MVC5 существует такой замечательный хелпер как

Html.BeginForm()

Он может записываться как

@Html.BeginForm()
...
@Html.EndForm()

Так и

@using (Html.BeginForm())
{
    ...
}

Как создать пользовательский хелпер по такому принципу. Например мне нужен блок div, блок не голый, а в нём какие-то основные элементы, допустим пять ссылок. Мне этот блок нужно дублировать постоянно, помимо фиксированных пяти ссылок нужно внутрь пихать кучу других элементов, это может быть кнопка/таблица/картинка/и т.д. Так вот, как это можно реализовать с помощью таких же красивых фигурных скобочек, а не писать Html.MyPerfectDivStart() и Html.MyPerfectDivEnd()

Есть вариант использовать MvcHtmlString и передавать в качестве параметра List<MvcHtmlString> из разных других компонентов, созданных мною. Но это некрасиво смотрится!

Answer 1

Более подробно то, что описывал в комментариях.

Во-первых, сами extension для открытия/закрытия:

public static class MyDivHelper
{
    public static MvcDiv BeginDiv(this HtmlHelper htmlHelper)
    {
        htmlHelper.ViewContext.Writer.Write("<div style='asdf'>");
        return new MvcDiv(htmlHelper.ViewContext);
    }
    public static void EndDiv(ViewContext viewContext)
    {
        viewContext.Writer.Write("</div>");
        viewContext.OutputClientValidation();
    }
}

Во-вторых, disposing для закрывающего div'а:

public class MvcDiv : IDisposable
{
    private readonly ViewContext _viewContext;
    private bool _disposed;
    public MvcDiv(ViewContext viewContext)
    {
        if (viewContext == null)
        {
            throw new ArgumentNullException("viewContext");
        }
        _viewContext = viewContext;
    }
    public void Dispose()
    {
        Dispose(true /* disposing */);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            _disposed = true;
            MyDivHelper.EndDiv(_viewContext);
        }
    }
}

В-третьих, собственно использование с using:

@using (Html.BeginDiv())
{
}

Пример рабочий, проверил.

PS Спасибо за любопытный вопрос. Ответа не знал, но появился хороший повод заглянуть в исходники mvc.

READ ALSO
MVP pattern+async+update UI

MVP pattern+async+update UI

Есть некая задача, по которой надо обработать данные в массиве из большого количества элементовДанные, это кадастровые номера, по которым...

464
Работа с XML средствами C#

Работа с XML средствами C#

Имееться xml файл, нужно из этого файла выцедить и записать в лист, проблема в том что у меня получаеться выцедить только 1 экземпляр

252
ComboBox в grid KENDO winform, загрузка и добавление

ComboBox в grid KENDO winform, загрузка и добавление

Grid загружается через BindingSource, в grid включено добавление, удаление, редактированиеКак сделать так что бы в первом столбце находился combobox и при...

199
Построение дерева по Хаффману C#

Построение дерева по Хаффману C#

Проблема заключается в коллекции param, в которой создаётся деревоС первыми двумя выражениями все нормально

226