2014-06-23 3 views
1

На данный момент это скорее теоретический вопрос, но здесь все идет.Переопределить помощник html по умолчанию с расширением в MVC?

Короткая версия: Есть какой-то способ сделать свой собственный HTML помощник заменить стандартный HTML помощник (как EditBoxFor), не выходя Заменить все маршрут (переопределяет помощник по умолчанию?) Или ограничить заменить все функции в VS на только мнения?

Длинная версия: Мы создали приложение MVC с множеством видов, но теперь наш клиент хочет, чтобы мы добавили функциональность, которая позволит ему изменять текст в приложении. Это связано с такими вещами, как ярлыки для входов, заполнители и некоторые такие. Я уже написал свою собственную замену помощника html для EditBoxFor (в ее сердце все еще используется и EditBoxFor), который загружает местозаполнитель и т. Д. Из базы данных помещает его в кеш и так далее. Я назвал его (ах так умно) EditBoxFor2, и он принимает те же самые входы, что и EditBoxFor, поэтому я могу просто добавить 2 к имени помощника и поддерживает эту новую текстовую функциональность. EditBoxFor используется в системе много раз, и это не единственный помощник html, который мы модифицируем. Я мог бы, вероятно, заменить все EditBoxForEditBoxFor (или еще лучше Html.EditBoxFor( с Html.EditBoxFor2() вместо того, чтобы сменить несколько тысяч строк кода вручную, но очень вероятно, что я разорву некоторые виды \ контроллеров \ других помощников таким образом (я мог бы забыли реализовать несколько вариантов EditBoxFor в моем Html.EditBoxFor2). Поэтому мне было интересно, есть ли способ переопределить (как в том же имени и тех же входных параметрах) по умолчанию помощники с моим собственным?

+1

Для этого нет хорошего способа, и для этого есть причина. Даже если вы сейчас единственный разработчик, работающий над этим, это может быть не всегда так. Вы можете отправиться на более зеленые пастбища, или ваша организация может привлечь кого-то еще. Переопределение подобных вещей служит только для создания путаницы в вашей кодовой базе. Используя другой, называемый помощник, вы даете понять, что он * * отличается. –

+0

Наверняка это решение должно быть оставлено до команды разработчиков? Как это отличается от переопределения любого другого типа поведения по умолчанию, такого как «ModelMetadataProviders» или даже глобальные фильтры действий? –

ответ

0

Как писал Прэтт, нет хорошего способа сделать это и это возможно, не такая хорошая идея сделать это в первую очередь. Это может оказаться очень запутанным для других людей, работающих над проектом (я уже испытал это, когда другие разработчики изменили некоторые основные действия приложения MVC, а затем мне пришлось потратить часы, чтобы найти причину, по которой что-то основное не работает в ожидаемый путь).

2

Вы можете сделать это, указав шаблон дисплея или шаблон редактора (это ключевые слова, которые вы можете использовать для Google).

Короче говоря, вы создаете папку «DisplayTemplates» и папку «EditorTemplates» в вашей папке ~/Views/Shared. Это соглашение.

Затем в этих папках вы можете добавить шаблон для каждого редактора по умолчанию.

Я использую его для создания шаблона для своих номеров телефонов, например.

PhoneNumber.cshtml (должно быть имя вашего класса)

@model MyProject.Common.Models.PhoneNumber 
<div class="editor-field"> 
    @Html.DisplayFor(model => model.PhoneNumberType) 
    @Html.DisplayFor(model => model.Phone) 
</div> 

Я также использую его, чтобы иметь дисплей для моих перечислений

DisplayTemplates/String.cshtml

@using MyProject.Website.Helpers 

@{ 
    var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType; 

    @(typeof(Enum).IsAssignableFrom(type) ? EnumViewsHelpers.GetResourceValueForEnumValue(Model) : Model) 
} 

Таким образом, каждый раз, когда у меня есть поле типа enum для отображения, оно будет называть меня lper, чтобы отобразить его. Помощник будет искать соответствующую строку в файле resources.resx.

Что касается редактора, он будет отображать DropDownList, чтобы выбрать перечисление вы хотите

EditorTemplates/String.cshtml

@using System.Web.Mvc.Html 
@using MyProject.Website.Helpers 

@{ 
    var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType; 

    @(typeof(Enum).IsAssignableFrom(type) ? Html.ExtEnumDropDownListFor(x => x) : Html.TextBoxFor(x => x)) 
} 

Это вспомогательная

public static class EnumViewsHelpers 
{ 
    public static IHtmlString ExtEnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, TEnum>> expression) 
    { 
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 

    var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType; 

    var enumValues = Enum.GetValues(enumType).Cast<object>(); 

    var items = from enumValue in enumValues 
       select new SelectListItem 
       { 
        Text = GetResourceValueForEnumValue(enumValue), 
        Value = ((int)enumValue).ToString(), 
        Selected = enumValue.Equals(metadata.Model) 
       }; 

    return html.DropDownListFor(expression, items, string.Empty, null); 
} 

public static string GetResourceValueForEnumValue<TEnum>(TEnum enumValue) 
{ 
    var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue); 

    return Resource.ResourceManager.GetString(key) ?? enumValue.ToString(); 
    } 
} 

Я думаю, что вы можете использовать ту же технику для редакторов

+0

Спасибо за ответ, я слышал о шаблонах редактора, но я думал, что могу использовать их только с помощником EditorFor, я думаю, мне придется исследовать его немного больше. Постскриптум Ваш второй пример кода просочился через «}» вне кода. – jahu

+0

Вы можете использовать их только в сочетании с 'EditorFor' или' DisplayFor'. Я полагаю, что @MarcinHabuszewski не читал это близко и ошибался «EditBoxFor» для 'EditorFor'. Сначала я прочитал его так же. –

Смежные вопросы