ASP.NET MVC 3 自定义 HTML 帮助程序 - 最佳实践/使用

发布于 2024-10-14 01:57:20 字数 419 浏览 1 评论 0原文

MVC 新手,并且已经完成了 ASP.NET 网站上的教程。

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

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

举个例子,我正在考虑编写一个自定义助手来格式化我需要在不同地方显示的日期,但现在担心可能有一个更优雅的解决方案(IE DataAnnotations in my models)

有什么想法吗?

编辑:

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

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

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

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.

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)

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浴红衣 2024-10-21 01:57:20

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

  • Html.BodyId():生成一个传统的 body id 标记,以便在为视图添加自定义 css 时进行引用。
  • Html.SubmitButton(string):生成 input[type=submit] 或 button[type=submit] 元素,具体取决于我想要如何设置按钮的样式。
  • Html.Pager(IPgedList):用于从分页列表模型生成分页控件。
  • 等等......

我最喜欢的 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,所有标签、输入、提示和验证消息都在您的页面上。同样,您可以在模型上使用属性并对其进行反思,以获得真正的智能和 DRY。当然,如果您无法标准化表单设计,这将是浪费时间。然而,对于简单的情况,CSS 可以提供您需要的所有自定义,它可以工作 grrrrrrrrrreat!

这个故事的寓意是——HtmlHelpers 可以使您免受全局设计更改的影响,这些更改会在视图中破坏手工制作的标记。我喜欢他们。但你可能会太过分,有时部分视图比编码助手更好。 我用来决定助手与部分视图之间的一般经验法则:如果 HTML 块需要大量条件逻辑或编码技巧,我会使用助手(将代码放在应该放置的位置);如果没有,如果我只是输出没有太多逻辑的常见标记,我会使用部分视图(将标记放在应该标记的位置)。

希望这能给您一些想法!

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:

  • Html.BodyId(): generates a conventional body id tag for referencing when adding custom css for a view.
  • Html.SubmitButton(string): generates either an input[type=submit] or button[type=submit] element, depending on how I want to style the buttons.
  • Html.Pager(IPagedList): For generating paging controls from a paged list model.
  • 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:

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!

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

Hope this gives you some ideas!

浮生未歇 2024-10-21 01:57:20

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

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

然后简单地说:

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

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


更新:

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

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

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

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

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


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:

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.

若沐 2024-10-21 01:57:20
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);
}
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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文