ASP.NET MVC 3 Custom HTML Helpers - лучшие практики / использование - PullRequest
32 голосов
/ 26 января 2011

Новичок в MVC и проходил обучение на сайте asp.net.

Они включают пример пользовательского помощника html для усечения длинного текста, отображаемого в таблице.

Просто интересно, какие другие решения люди придумали, используя HTML-помощники, и есть ли какие-либо рекомендации или вещи, которых следует избегать при их создании / использовании.

В качестве примера я рассматривал написание специального помощника для форматирования дат, которые мне нужно отображать в разных местах, но теперь я обеспокоен тем, что может быть более элегантное решение (IE DataAnnotations в моих моделях)

Есть мысли?

РЕДАКТИРОВАТЬ:

Еще одно потенциальное использование, о котором я только что подумал ... Конкатенация строк.Пользовательский помощник может принять идентификатор пользователя в качестве входных данных и вернуть полное имя пользователя ... Результатом может быть некоторая форма (Заголовок) (Первый) (Средний) (Последний) в зависимости от того, какие из этих полей доступны.Просто мысль, я еще не пробовал ничего подобного.

Ответы [ 3 ]

100 голосов
/ 27 января 2011

Я использую HtmlHelpers все время, чаще всего для инкапсуляции генерации шаблонного HTML, на случай, если я передумаю. У меня были такие помощники как:

  • Html.BodyId (): генерирует обычный тег id тела для ссылки при добавлении пользовательского css для представления.
  • Html.SubmitButton (string): генерирует элемент input [type = submit] или button [type = submit], в зависимости от того, как я хочу стилизовать кнопки.
  • Html.Pager (IPagedList): для создания элементов управления подкачкой из модели списка с подкачкой.
  • и т.д ....

Одним из моих любимых применений для HtmlHelpers является СУШКА разметки обычной формы. Обычно у меня есть контейнер div для строки формы, один div для метки и одна метка для ввода, сообщений проверки, текста подсказки и т. Д. В конечном итоге это может привести к множеству шаблонных тегов html. Вот пример того, как я справился с этим:

public static MvcHtmlString FormLineDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string labelText = null, string customHelpText = null, object htmlAttributes = null)
{
    return FormLine(
        helper.LabelFor(expression, labelText).ToString() +
        helper.HelpTextFor(expression, customHelpText),
        helper.DropDownListFor(expression, selectList, htmlAttributes).ToString() +
        helper.ValidationMessageFor(expression));
}

public static MvcHtmlString FormLineEditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string templateName = null, string labelText = null, string customHelpText = null, object htmlAttributes = null)
{
    return FormLine(
        helper.LabelFor(expression, labelText).ToString() +
        helper.HelpTextFor(expression, customHelpText),
        helper.EditorFor(expression, templateName, htmlAttributes).ToString() +
        helper.ValidationMessageFor(expression));
}

private static MvcHtmlString FormLine(string labelContent, string fieldContent, object htmlAttributes = null)
{
    var editorLabel = new TagBuilder("div");
    editorLabel.AddCssClass("editor-label");
    editorLabel.InnerHtml += labelContent;

    var editorField = new TagBuilder("div");
    editorField.AddCssClass("editor-field");
    editorField.InnerHtml += fieldContent;

    var container = new TagBuilder("div");
    if (htmlAttributes != null)
        container.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    container.AddCssClass("form-line");
    container.InnerHtml += editorLabel;
    container.InnerHtml += editorField;

    return MvcHtmlString.Create(container.ToString());
}

public static MvcHtmlString HelpTextFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string customText = null)
{
    // Can do all sorts of things here -- eg: reflect over attributes and add hints, etc...
}    

Как только вы это сделаете, вы можете вывести строки формы следующим образом:

<%: Html.FormLineEditorFor(model => model.Property1) %>
<%: Html.FormLineEditorFor(model => model.Property2) %>
<%: Html.FormLineEditorFor(model => model.Property3) %>

... и BAM, все ваши метки, входные данные, подсказки и сообщения проверки находятся на вашей странице. Опять же, вы можете использовать атрибуты на своих моделях и размышлять над ними, чтобы стать по-настоящему умными и СУХИМИ. И, конечно, это было бы пустой тратой времени, если вы не можете стандартизировать дизайн вашей формы. Тем не менее, для простых случаев, когда css может предоставить все необходимые настройки, это работает grrrrrrrrreat!

Мораль истории - HtmlHelpers может оградить вас от глобальных изменений дизайна, разрушающих созданную вручную разметку в представлении после просмотра. Они мне нравятся. Но вы можете пойти за борт, и иногда частичные представления лучше, чем закодированные помощники. Общее практическое правило, которое я использую для выбора между вспомогательным и частичным представлением: если кусок HTML требует много условной логики или хитрости кодирования, я использую помощника (поместите код там, где должен быть код); если нет, то если я просто выводю общую разметку без особой логики, я использую частичное представление (поместите разметку там, где должна быть разметка).

Надеюсь, это даст вам некоторые идеи!

16 голосов
/ 26 января 2011

Хорошо в случае форматирования атрибута DisplayFormat может быть хорошим решением:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Date { get; set; }

, а затем просто:

@Html.DisplayFor(x => x.Date)

Что касается усеченияСтрока связана с тем, что пользовательский помощник HTML - хорошее решение.


ОБНОВЛЕНИЕ:

Что касается EDIT, пользовательский помощник HTML может работать в этой ситуации, но есть и альтернативный подход, которыйочень нравится: просмотр моделей.Так что, если в этом конкретном представлении вы всегда будете показывать объединение имен, вы можете определить модель представления:

public class PersonViewModel
{
    public string FullName { get; set; }
}

Теперь контроллер собирается запросить хранилище, чтобы получить модель и затем отобразитьэта модель для модели представления, которая будет передана в представление, чтобы представление могло просто @Html.DisplayFor(x => x.FullName).Сопоставление моделей и моделей представлений можно упростить с помощью таких структур, как AutoMapper .

.
0 голосов
/ 05 июля 2018
public static HtmlString OwnControlName<T, U>(this HtmlHelper<T> helper, Expression<Func<T, U>> expression, string label_Name = "", string label_Title = "", Attr attr = null)
        {
            TemplateBuilder tb = null;
            string template = null;
          if (expression == null) throw new ArgumentException("expression");
 obj = helper.ViewData.Model;
                tb.Build(obj, expression.Body as MemberExpression, typeof(T), new SimpleTemplate(new TextArea()), label_Name, label_Title, attr);
                template = tb.Get();
 return new MvcHtmlString(template);
}
...