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

ste*_*776 32 asp.net-mvc html-helper asp.net-mvc-3 asp.net-mvc-2

MVC的新手,并且已经在asp.net网站上运行了教程.

它们包含一个自定义html帮助程序示例,用于截断表中显示的长文本.

只是想知道人们使用HTML帮助程序提出了哪些其他解决方案,以及在创建/使用它们时是否有任何最佳实践或要避免的事项.

作为一个例子,我正在考虑编写一个自定义助手来格式化我需要在各个地方显示的日期,但我现在担心可能有一个更优雅的解决方案(我的模型中的IE DataAnnotations)

有什么想法吗?

编辑:

我刚才想到的另一个潜在用途......字符串连接.自定义帮助程序可以将userID作为输入并返回用户全名...结果可以是(标题)(第一个)(中)(最后)的某种形式,具体取决于哪些字段可用.只是一个想法,我还没有尝试过这样的事情.

spo*_*pot 100

我一直使用HtmlHelpers,最常见的是封装样板HTML的生成,以防我改变主意.我有这样的帮助:

  • Html.BodyId():在为视图添加自定义css时生成传统的body id标记以供引用.
  • Html.SubmitButton(string):生成输入[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...
}    
Run Code Online (Sandbox Code Playgroud)

但是,完成此操作后,您可以输出如下的表单行:

<%: Html.FormLineEditorFor(model => model.Property1) %>
<%: Html.FormLineEditorFor(model => model.Property2) %>
<%: Html.FormLineEditorFor(model => model.Property3) %>
Run Code Online (Sandbox Code Playgroud)

...和BAM,您的所有标签,输入,提示和验证消息都在您的页面上.同样,您可以在模型上使用属性并反映它们以获得真正的智能和干燥.当然,如果你不能标准化你的表单设计,这将浪费时间.但是,对于简单的情况,css可以提供您需要的所有自定义,它可以运行grrrrrrrrrreat!

故事的道德 - HtmlHelpers可以使您免受全局设计变更的影响,在视图之后破坏手工制作的标记.我喜欢他们.但是你可以过火,有时局部视图比编码助手更好.我用来决定辅助视图和部分视图之间的一般经验法则:如果HTML的大块需要很多条件逻辑或编码技巧,我使用一个帮助器(把代码放在代码应该的地方); 如果没有,如果我只是在没有太多逻辑的情况下输出公共标记,我使用局部视图(将标记放在标记应该是的位置).

希望这会给你一些想法!

  • 很好的答案.我花了一点时间才发现我需要使用System.Web.Mvc.Html; 获得.EditorFor扩展显示 (7认同)
  • 好帖子!如果你不介意,我肯定会从这里复制/粘贴一些;) (3认同)

Dar*_*rov 16

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

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

然后简单地说:

@Html.DisplayFor(x => x.Date)
Run Code Online (Sandbox Code Playgroud)

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


更新:

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

public class PersonViewModel
{
    public string FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,控制器将查询存储库以获取模型,然后将此模型映射到视图模型,该模型将传递给视图,以便视图可以简单@Html.DisplayFor(x => x.FullName).使用AutoMapper等框架可以简化模型和视图模型之间的映射.

  • 很有意思.几乎看起来像自定义的HTML帮助程序是最后的手段. (4认同)