重构类似的CHTML,使用EditorFor和LabelFor呈现不同的属性

Pat*_*ick 3 c# asp.net-mvc razor

我正在构建一个项目,其中包含许多关于剃刀视图的常用代码.

例:

<div class="form-group">
    @Html.LabelFor(model => model.LayoutFrontAmount, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => model.LayoutFrontAmount, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => model.LayoutFrontAmount, "", new { @class = "text-danger" })</span>
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.LayoutFrontBackAmount, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => model.LayoutFrontBackAmount, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => model.LayoutFrontBackAmount, "", new { @class = "text-danger" })</span>
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.LayoutTRC, htmlAttributes: new { @class = "control-label col-xs-12 col-sm-4 col-md-3" })
    <div class="col-xs-4 col-sm-2 col-md-2 col-lg-1">
        @Html.EditorFor(model => model.LayoutTRC, new { htmlAttributes = new { @class = "form-control" } })
    </div>
    <div class="col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3">
        <span class="help-block">@Html.ValidationMessageFor(model => model.LayoutTRC, "", new { @class = "text-danger" })</span>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

唯一改变的是Model的属性.

有没有办法用以下代码替换所有代码:

@TemplateName1(model => model.LayoutFrontAmount)
@TemplateName1(model => model.LayoutFrontBackAmount)
@TemplateName1(model => model.LayoutTRC)
Run Code Online (Sandbox Code Playgroud)

小智 5

您可以创建一个HtmlHelper扩展方法,该方法将为属性生成所有html,包括label和input元素

using System;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace YourAssembly.Html
{
  public static class BootstrapHelper
  {
    public static MvcHtmlString BootstrapEditorFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
    {      
      MvcHtmlString label = LabelExtensions.LabelFor(helper, expression, new { @class = "control-label col-xs-12 col-sm-4 col-md-3" });
      MvcHtmlString editor = EditorExtensions.EditorFor(helper, expression, new { htmlAttributes = new { @class = "form-control" } });
      MvcHtmlString validation = ValidationExtensions.ValidationMessageFor(helper, expression, null, new { @class = "text-danger" });

      // Build the input elements
      TagBuilder editorDiv = new TagBuilder("div");
      editorDiv.AddCssClass("col-xs-4 col-sm-2 col-md-2 col-lg-1");
      editorDiv.InnerHtml = editor.ToString();
      // Build the validation message elements
      TagBuilder validationSpan = new TagBuilder("span");
      validationSpan.AddCssClass("help-block");
      validationSpan.InnerHtml = validation.ToString();
      TagBuilder validationDiv = new TagBuilder("div");
      validationDiv.AddCssClass("col-xs-12 col-md-8 col-sm-offset-4 col-md-offset-3");
      validationDiv.InnerHtml = validationSpan.ToString();
      // Combine all elements
      StringBuilder html = new StringBuilder();
      html.Append(label.ToString());
      html.Append(editorDiv.ToString());
      html.Append(validationDiv.ToString());
      // Build the outer div
      TagBuilder outerDiv = new TagBuilder("div");
      outerDiv.AddCssClass("form-group");
      outerDiv.InnerHtml = html.ToString();
      return MvcHtmlString.Create(outerDiv.ToString());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以在web.config文件中注册(意味着您不需要@using ...在视图中)

<namespaces>
  <add namespace="System.Web.Mvc" />
  ....
  <add namespace="yourAssembly.Html " /> // add this
</namespaces>
Run Code Online (Sandbox Code Playgroud)

现在,在主视图中,您可以使用以下3行代码生成问题中显示的所有html

@Html.BootstrapEditorFor(m => m.LayoutFrontAmount)
@Html.BootstrapEditorFor(m => m.LayoutFrontBackAmount)
@Html.BootstrapEditorFor(m => m.LayoutTRC)
Run Code Online (Sandbox Code Playgroud)

如果您希望这可以在多个项目中重用,请在单独的dll中编译它,并在项目中添加对它的引用.