ASP。NET MVC 3自定义HTML助手-最佳实践/使用

时间:2022-01-11 03:25:10

New to MVC and have been running through the tutorials on the asp.net website.

是MVC的新手,一直在运行asp.net网站上的教程。

They include an example of a custom html helper to truncate long text displayed in a table.

它们包括一个自定义html助手的示例,用于截断表中显示的长文本。

Just wondering what other solutions people have come up with using HTML helpers and if there are any best practices or things to avoid when creating/using them.

只是想知道人们使用HTML helper时还会有什么解决方案,以及在创建/使用它们时是否需要避免什么最佳实践或事情。

As an example, I was considering writing a custom helper to format dates that I need to display in various places, but am now concerned that there may be a more elegant solution(I.E. DataAnnotations in my models)

例如,我正在考虑编写一个自定义帮助程序来格式化我需要在不同地方显示的日期,但是现在我担心可能会有一个更优雅的解决方案(即DataAnnotations在我的模型)

Any thoughts?

任何想法吗?

EDIT:

编辑:

Another potential use I just thought of...String concatenation. A custom helper could take in a userID as input and return a Users full name... The result could be some form of (Title) (First) (Middle) (Last) depending on which of those fields are available. Just a thought, I have not tried anything like this yet.

我刚刚想到的另一个潜在用途……字符串连接。自定义帮助程序可以接收用户id作为输入,并返回用户的全名……结果可以是(Title) (First) (Middle) (Last)的某种形式,这取决于哪些字段可用。只是一个想法,我还没有尝试过这样的事情。

2 个解决方案

#1


16  

Well in the case of formatting the DisplayFormat attribute could be a nice solution:

在格式化DisplayFormat属性的情况下是一个很好的解决方案:

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

and then simply:

然后简单:

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

As far as truncating string is concerned a custom HTML helper is a good solution.

就截断字符串而言,自定义HTML助手是一个很好的解决方案。


UPDATE:

更新:

Concerning your EDIT, a custom HTML helper might work in this situation but there's also an alternative approach which I like very much: view models. So if in this particular view you are always going to show the concatenation of the names then you could define a view model:

关于您的编辑,一个自定义HTML助手可能在这种情况下工作,但是还有一个我非常喜欢的替代方法:查看模型。所以如果在这个特定的视图中你总是要显示名字的串联那么你可以定义一个视图模型

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

Now the controller is going to query the repository to fetch the model and then map this model to a view model which will be passed to the view so that the view could simply @Html.DisplayFor(x => x.FullName). The mapping between models and view models could be simplified with frameworks like AutoMapper.

现在,控制器将查询存储库以获取模型,然后将模型映射到视图模型,视图模型将被传递给视图,这样视图就可以简单地使用@Html了。DisplayFor(x = > x.FullName)。模型和视图模型之间的映射可以用AutoMapper之类的框架来简化。

#2


101  

I use HtmlHelpers all the time, most commonly to encapsulate the generation of boilerplate HTML, in case I change my mind. I've had such helpers as:

我一直使用htmlhelper (HTML helper),最常见的是封装样板HTML的生成,以防我改变主意。我有这样的帮手:

  • Html.BodyId(): generates a conventional body id tag for referencing when adding custom css for a view.
  • bodyid():为视图添加定制的css时,生成一个常规的body id标签。
  • Html.SubmitButton(string): generates either an input[type=submit] or button[type=submit] element, depending on how I want to style the buttons.
  • Html.SubmitButton(string):生成输入[type=submit]或按钮[type=submit]元素,这取决于我想如何样式化按钮。
  • Html.Pager(IPagedList): For generating paging controls from a paged list model.
  • Html.Pager(IPagedList):用于从分页列表模型生成分页控件。
  • etc....
  • 等....

One of my favorite uses for HtmlHelpers is to DRY up common form markup. Usually, I have a container div for a form line, one div for the label, and one label for the input, validation messages, hint text, etc. Ultimately, this could end up being a lot of boilerplate html tags. An example of how I have handled this follows:

htmlhelper的一个我最喜欢的用途是消除常见的表单标记。通常,我有一个用于表单行的容器div,一个用于标签的div,以及一个用于输入、验证消息、提示文本等的标签。下面是我如何处理这个问题的一个例子:

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...
}    

Once you've done this, though, you can output form lines like this:

一旦你这样做了,你就可以输出像这样的线条:

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

... and BAM, all your labels, inputs, hints, and validation messages are on your page. Again, you can use attributes on your models and reflect over them to get really smart and DRY. And of course this would be a waste of time if you can't standardize on your form design. However, for simple cases, where css can supply all the customization you need, it works grrrrrrrrreat!

…BAM,所有的标签、输入、提示和验证消息都在页面上。同样,您可以使用模型上的属性并对其进行反射,使其变得非常智能和枯燥。当然,如果不能对表单设计进行标准化,这将是浪费时间。但是,对于简单的情况,css可以提供您需要的所有定制,它可以工作grrrrrrrrreat!

Moral of the story -- HtmlHelpers can insulate you from global design changes wrecking hand crafted markup in view after view. I like them. But you can go overboard, and sometimes partial views are better than coded helpers. A general rule of thumb I use for deciding between helper vs. partial view: If the chunk of HTML requires a lot of conditional logic or coding trickery, I use a helper (put code where code should be); if not, if I am just outputting common markup without much logic, I use a partial view (put markup where markup should be).

故事的寓意——htmlhelper (html助手)可以将您与全局设计更改隔离开来,从而在一个又一个视图中破坏手工制作的标记。我喜欢他们。但是您可能做得太过火了,有时候部分视图比编码助手要好。在帮助视图和部分视图之间进行选择时,我使用的一个通用经验法则是:如果HTML块需要大量的条件逻辑或编码技巧,我就使用帮助器(将代码放在代码应该在的地方);如果不是,如果我只是输出没有太多逻辑的公共标记,我就使用部分视图(将标记放在标记应该在的地方)。

Hope this gives you some ideas!

希望这能给你一些建议!

#1


16  

Well in the case of formatting the DisplayFormat attribute could be a nice solution:

在格式化DisplayFormat属性的情况下是一个很好的解决方案:

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

and then simply:

然后简单:

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

As far as truncating string is concerned a custom HTML helper is a good solution.

就截断字符串而言,自定义HTML助手是一个很好的解决方案。


UPDATE:

更新:

Concerning your EDIT, a custom HTML helper might work in this situation but there's also an alternative approach which I like very much: view models. So if in this particular view you are always going to show the concatenation of the names then you could define a view model:

关于您的编辑,一个自定义HTML助手可能在这种情况下工作,但是还有一个我非常喜欢的替代方法:查看模型。所以如果在这个特定的视图中你总是要显示名字的串联那么你可以定义一个视图模型

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

Now the controller is going to query the repository to fetch the model and then map this model to a view model which will be passed to the view so that the view could simply @Html.DisplayFor(x => x.FullName). The mapping between models and view models could be simplified with frameworks like AutoMapper.

现在,控制器将查询存储库以获取模型,然后将模型映射到视图模型,视图模型将被传递给视图,这样视图就可以简单地使用@Html了。DisplayFor(x = > x.FullName)。模型和视图模型之间的映射可以用AutoMapper之类的框架来简化。

#2


101  

I use HtmlHelpers all the time, most commonly to encapsulate the generation of boilerplate HTML, in case I change my mind. I've had such helpers as:

我一直使用htmlhelper (HTML helper),最常见的是封装样板HTML的生成,以防我改变主意。我有这样的帮手:

  • Html.BodyId(): generates a conventional body id tag for referencing when adding custom css for a view.
  • bodyid():为视图添加定制的css时,生成一个常规的body id标签。
  • Html.SubmitButton(string): generates either an input[type=submit] or button[type=submit] element, depending on how I want to style the buttons.
  • Html.SubmitButton(string):生成输入[type=submit]或按钮[type=submit]元素,这取决于我想如何样式化按钮。
  • Html.Pager(IPagedList): For generating paging controls from a paged list model.
  • Html.Pager(IPagedList):用于从分页列表模型生成分页控件。
  • etc....
  • 等....

One of my favorite uses for HtmlHelpers is to DRY up common form markup. Usually, I have a container div for a form line, one div for the label, and one label for the input, validation messages, hint text, etc. Ultimately, this could end up being a lot of boilerplate html tags. An example of how I have handled this follows:

htmlhelper的一个我最喜欢的用途是消除常见的表单标记。通常,我有一个用于表单行的容器div,一个用于标签的div,以及一个用于输入、验证消息、提示文本等的标签。下面是我如何处理这个问题的一个例子:

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...
}    

Once you've done this, though, you can output form lines like this:

一旦你这样做了,你就可以输出像这样的线条:

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

... and BAM, all your labels, inputs, hints, and validation messages are on your page. Again, you can use attributes on your models and reflect over them to get really smart and DRY. And of course this would be a waste of time if you can't standardize on your form design. However, for simple cases, where css can supply all the customization you need, it works grrrrrrrrreat!

…BAM,所有的标签、输入、提示和验证消息都在页面上。同样,您可以使用模型上的属性并对其进行反射,使其变得非常智能和枯燥。当然,如果不能对表单设计进行标准化,这将是浪费时间。但是,对于简单的情况,css可以提供您需要的所有定制,它可以工作grrrrrrrrreat!

Moral of the story -- HtmlHelpers can insulate you from global design changes wrecking hand crafted markup in view after view. I like them. But you can go overboard, and sometimes partial views are better than coded helpers. A general rule of thumb I use for deciding between helper vs. partial view: If the chunk of HTML requires a lot of conditional logic or coding trickery, I use a helper (put code where code should be); if not, if I am just outputting common markup without much logic, I use a partial view (put markup where markup should be).

故事的寓意——htmlhelper (html助手)可以将您与全局设计更改隔离开来,从而在一个又一个视图中破坏手工制作的标记。我喜欢他们。但是您可能做得太过火了,有时候部分视图比编码助手要好。在帮助视图和部分视图之间进行选择时,我使用的一个通用经验法则是:如果HTML块需要大量的条件逻辑或编码技巧,我就使用帮助器(将代码放在代码应该在的地方);如果不是,如果我只是输出没有太多逻辑的公共标记,我就使用部分视图(将标记放在标记应该在的地方)。

Hope this gives you some ideas!

希望这能给你一些建议!