Есть ли способ динамически обернуть / перехватить методы расширения HtmlHelper.Думаю, декоратор шаблон - PullRequest
5 голосов
/ 22 сентября 2011

Мне бы хотелось, чтобы методы расширения / перехвата HtmlHelper (TextBox, Hidden и т. Д.), Предоставляемые в System.Web.Mvc.Html, позволяли повторно использовать одни и те же частичные представления в 2 отдельных случаях использования. Без частичного:

@model BlogEntry

@Html.TextBoxFor(t => t.Title)
@Html.TextAreaFor(t => t.Body)
@* Etc *@

Вызывающий Partial будет знать контекст (т. Е. Переопределять или оставлять имп MS).

Причина переопределения различна. Например: использовать в шаблонах JQuery, где вывод для атрибута value будет «$ {Title}» в приведенном выше примере, или добавить метаданные Html5.

Ответы [ 2 ]

3 голосов
/ 22 сентября 2011

Я не уверен, что вы беспокоитесь о добавлении собственных методов расширения - почему вам нужно «создать свою собственную страницу базового вида и полностью вступить во владение». Вы можете вызывать своих пользовательских помощников на любой странице так же, как и встроенные помощники:

@Html.TextBoxFor(x => x.Name)
@Html.MyTextBoxFor(x => x.Name)

Кроме того, вы можете добавить некоторый параметр флага в ваш метод, чтобы контролировать, выполняет ли он просто функциональность по умолчанию или что-то настраиваемое.

Когда вы создаете свои собственные методы расширения, вам придется либо изменить подпись, либо имя метода.

Раньше я использовал уникальные имена, но в итоге обнаружил, что действительно хочу иметь возможность быстро отличить свои собственные реализации от значений по умолчанию, поэтому иногда я использую:

@Html.Custom().TextBoxFor(…
@Html.Custom().TextAreaFor(…

По сути, вы создаете один новый метод расширения, который принимает HtmlHelper<T> и возвращает CustomHelpers<T>.

    public static CustomHelpers<TModel> Custom<TModel>(this HtmlHelper<TModel> html)
    {
        return new CustomHelpers<TModel>(html);
    }

Класс CustomHelpers<T> определяет все ваши собственные реализации:

    public class CustomHelpers<TModel>
    {
        private readonly HtmlHelper<TModel> _html;

        public CustomHelpers(HtmlHelper<TModel> html) { _html = html; }

        public MvcHtmlString TextBoxFor<TProperty>(Expression<Func<TModel, TProperty>> expression)
        {
            // because you have a reference to the "native" HtmlHelper<TModel>, you
            // can use it here and extend or modify the result, almost like a decorator;
            // you can get the "native" result by calling _html.TextBoxFor(expression)
        }

Итак, ваше «переопределение» TextBoxFor может получить флаг из вашего частичного представления, чтобы определить, возвращает ли он собственный результат или что-то специфическое для контекста.

Опять же, класс CustomHelpers<T> не является обязательным. Вы будете добавлять параметр флага или что-то похожее на подпись ваших пользовательских помощников, поэтому вы не будете сталкиваться с существующими помощниками.

Преимущество, которое он дает, состоит в том, чтобы потенциально именовать ваших помощников. Вы могли бы иметь:

@Html.TextBoxFor(…
@Html.JQuery().TextBoxFor(…
@Html.Mobile().TextBoxFor(…
0 голосов
/ 22 сентября 2011

Нет способа перехватить вызовы встроенных вспомогательных методов расширения. Однако вы можете написать свои собственные методы расширения, которые делают правильные вещи в зависимости от контекста.

...