标准化数据类型的复杂html视图的首选方法是什么?

时间:2015-05-05 00:06:09

标签: asp.net-mvc html-helper mvc-editor-templates

我有这样的代码,我在许多MVC编辑视图中重复。此示例是我们显示复选框的默认方式,但是在其他输入类型中找到了类似的重复。

<div class="form-group">
    @Html.LabelFor(model => model.IsLive, htmlAttributes: new { @class = "control-label col-md-3" })
    <div class="col-md-8 checkbox">
        <div class="col-xs-1">
            @Html.EditorFor(model => model.IsLive)
        </div>
        <div class="col-xs-10">
            @Html.CheckboxLabelFor(model => model.IsLive)
        </div>
    </div>
    <a class="infoonclick col-md-1" title="@Html.DisplayNameFor(model => model.IsLive)" data-content="@Html.DescriptionFor(model => model.IsLive)">
        <span class="fa fa-info-circle"></span>
    </a>
</div>

我想知道干燥和标准化的最佳方法是什么?

我想做@Html.DefaultCheckboxEditorFor(model => model.IsLive)

之类的事情

我尝试创建一个自定义的HtmlHelper,但这似乎涉及太多的硬编码字符串是一个好主意。

相反,我觉得我应该使用EditorTemplates,但我无法正确使用语法。视图的模型是一个bool,但我需要获取属性特定的东西,如显示名称和描述。

 @model bool


<div class="form-group">
    @Html.LabelFor(model => model.IsLive, htmlAttributes: new { @class = "control-label col-md-3" })
    <div class="col-md-8 checkbox">
        <div class="col-xs-1">
            @Html.EditorFor(model => model.IsLive)
        </div>
        <div class="col-xs-10">
            @Html.CheckboxLabelFor(model => model.IsLive)
        </div>
    </div>
    <a class="infoonclick col-md-1" title="@Html.DisplayNameFor(model => model.IsLive)" data-content="@Html.DescriptionFor(model => model.IsLive)">
        <span class="fa fa-info-circle"></span>
    </a>
</div>

1 个答案:

答案 0 :(得分:1)

我有一个项目,我的大多数观点都是这样的: (这也适用于多级深层复杂对象,但不适用于任何类型的集合,如IEnumerable,尽管可以对其进行修改)

<h3>Edit existing page</h3>

<div class="col-xs-12">
    @using (Html.BeginForm("Edit", "Page", FormMethod.Post, new { role = "role" }))
    {
      @Html.EditorForModel()
      <input type="submit" value="Save" class="btn btn-primary" />
    }
</div>

我觉得这很酷。所以模型看起来像:

public class PageEditViewModel
{
    [Editable(false)]
    [DisplayName("Page Id")]
    public Guid Id { get; set; }

    [Editable(false)]
    [DisplayName("Url to resource (format: '/my-resource' or '/sub/resource)'")]
    public string Url { get; set; }

    [Required]
    [MaxLength(50, ErrorMessage = "Maximum Length of 50 Exceeded.")]
    [DisplayName("Title for page (must match Url ex: 'My Resource' or 'Sub Resource'")]
    public string PageTitle { get; set; }

    [MaxLength(int.MaxValue, ErrorMessage = "Content Exceeded Maximum Length")]
    [DataType(DataType.MultilineText)]
    public string Content { get; set; }
}

我有一些编辑模板:

\视图\共用\ EditorTemplates \ multilinetext.cshtml

@model object
@{
  var htmlAttributes = this.ViewData.ModelMetadata.GetHtmlAttributes();
}

<div class="form-group @Html.ErrorClassFor(m => m, "has-error")">
    @Html.LabelFor(m => m, new { @class = "control-label" })
    <div class="controls">
        @Html.TextAreaFor(
            m => m,
            8, 8,
            htmlAttributes)
        @Html.ValidationMessageFor(m => m, null, new { @class = "help-block" })
    </div>
</div>

这一切都与object.cshtml的修改版本神奇地配合使用:

@model object

@using System.Text;
@using System.Data;

@{
  ViewDataDictionary viewData = Html.ViewContext.ViewData;
  TemplateInfo templateInfo = viewData.TemplateInfo;
  ModelMetadata modelMetadata = viewData.ModelMetadata;

  System.Text.StringBuilder builder = new StringBuilder();

  string result;

  // DDB #224751
  if (templateInfo.TemplateDepth > 2)
  {
     result = modelMetadata.Model == null ? modelMetadata.NullDisplayText
                                            : modelMetadata.SimpleDisplayText;
  }

  foreach (var prop in modelMetadata.Properties.Where(pm =>
     pm.ShowForEdit
        //&& pm.ModelType != typeof(System.Data.EntityState)
     && !templateInfo.Visited(pm)
     )
     .OrderBy(pm => pm.Order))
  {

     //Type modelType =  Model.GetType();
     Type modelType = modelMetadata.ModelType;
     System.Reflection.PropertyInfo pi = modelType.GetProperty(prop.PropertyName);
     System.ComponentModel.DataAnnotations.DisplayAttribute attribute = pi.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.DisplayAttribute;

     if (attribute != null
         && !string.IsNullOrWhiteSpace(attribute.GetGroupName()))
     {
        //builder.Append(string.Format("<div>{0}</div>", attribute.GetGroupName()));
        builder.Append(Html.Partial("Partial-GroupName", attribute.GetGroupName()));
     }

     builder.Append(Html.Editor(prop.PropertyName, prop.TemplateHint ?? prop.DataTypeName).ToHtmlString());
  }

  result = builder.ToString();
}
@Html.Raw(result)

示例输出:

EditForModel

我的EditFor模板是MacawNL BootstrapEditorTemplates的版本(我与之没有任何关系)。