为视图模型中的所有属性生成标签,文本框,验证消息

时间:2014-01-08 09:04:27

标签: c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-mvc-5

我有一个视图,我发现自己在视图模型中为所有属性重复相同的代码,如下所示:

查看

    @Html.LabelFor(m => m.UserName)
    @Html.TextBoxFor(m => m.UserName)
    @Html.ValidationMessageFor(m => m.UserName)

    @Html.LabelFor(m => m.Password)
    @Html.TextBoxFor(m => m.Password)
    @Html.ValidationMessageFor(m => m.Password)
    etc..

有没有办法在视图模型中为所有属性生成这三个元素而不必写出每个元素?我已经尝试循环遍历模型元数据属性但没有成功:

    @foreach(var property in ViewData.ModelMetadata.Properties)
    {

       @Html.LabelFor(property.PropertyName)
       @Html.TextBoxFor(property.PropertyName)
       @Html.ValidationMessageFor(property.PropertyName)

    }

错误:

  

无法从用法中推断出方法'System.Web.Mvc.Html.LabelExtensions.LabelFor(System.Web.Mvc.HtmlHelper,System.Linq.Expressions.Expression>)'的类型参数。

我已经用Google搜索了,但找不到一个好的解决方案。

4 个答案:

答案 0 :(得分:1)

您可以在模型字段上使用UIHint来简化它:

型号:

public class UserModel
{
    [UIHint("UserModelField")]
    public string Username { get; set; }
    [UIHint("UserModelField")]
    public string Password { get; set; }
}

EditorTemplate UserModelField.cshtml

@model string
@Html.LabelFor(m => m)
@Html.TextBoxFor(m => m)
@Html.ValidationMessageFor(m => m)

查看ViewUser.cshtml

@model UserModel
@Html.EditorFor(m => m.Username)
@Html.EditorFor(m => m.Password)

动作

public ActionResult ViewUser()
{
    var model = new UserModel { Username = "a", Password = "p" };
    return View(model);
} 

答案 1 :(得分:0)

快速回答是是的,有。您只需要覆盖Object模板,然后迭代您的模型属性,将它们发送到另一个模板,生成所有您想要的元素。

1 - 为整个EditorFor(您想要渲染所有属性的地方)调用Model助手:

@Html.EditorFor(x => x, "path_to_custom_Object.cshtml")

2 - 迭代您的属性(在Object.cshtml中):

foreach (var prop in ViewData.ModelMetadata.Properties)        
{
      @Html.Editor(prop.PropertyName, "path_to_custom_Template.cshtml")
}

3 - 构建所有元素(在Template.cshtml中):

@Html.LabelFor(x => x)
@Html.TextBoxFor(x => x)
@Html.ValidationMessageFor(x => x)

答案 2 :(得分:0)

this works fine:

@foreach(var property in ViewData.ModelMetadata.Properties)
{

   @Html.Label(property.PropertyName)
   @Html.TextBox(property.PropertyName)
   @Html.ValidationMessage(property.PropertyName)

}

答案 3 :(得分:0)

或者您总是可以编写一个HTML帮助程序来为您执行此操作: (所有方法都回溯到第一种方法,所以如果你想将结果包装成DIV左右,你只需要改变第一种方法)

    /// <summary>
    ///     Returns a completely formatted form element for the given expression, including label, input and validation messages
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    /// <typeparam name="TProperty"></typeparam>
    /// <param name="html"></param>
    /// <param name="propertyExpression"></param>
    /// <param name="editorHtml"></param>
    /// <param name="labelHtml"></param>
    /// <param name="validationHtml"></param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor<TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> propertyExpression,
        IHtmlString editorHtml,
        IHtmlString labelHtml,
        IHtmlString validationHtml)
    {
        return MvcHtmlString.Create(labelHtml.ToHtmlString() + editorHtml.ToHtmlString() +validationHtml.ToHtmlString());
    }

    /// <summary>
    ///     Method to build form input with label, editor and validation message.
    /// </summary>
    /// <example>
    ///     <code>
    ///         Html.FormElementFor(model => model.MyProperty)
    ///     </code>
    /// </example>
    /// <typeparam name="TModel">Model</typeparam>
    /// <typeparam name="TProperty">Property of the model</typeparam>
    /// <param name="html">This Html Helper</param>
    /// <param name="propertyExpression">Expression to get property of the model</param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor <TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> propertyExpression)
    {
        return html.FormElementFor(propertyExpression,
                                   html.EditorFor(propertyExpression),
                                   html.LabelFor(propertyExpression, new  { @class = "control-label" }),
                                   html.ValidationMessageFor(propertyExpression));
    }

    /// <summary>
    ///     Method to build form input with label, editor and validation message.
    /// </summary>
    /// <example>
    ///     <code>
    ///         Html.FormElementFor(model => model.MyProperty, Html.DropDownListFor(model => model.MyProperty, MySelectList))
    ///     </code>
    /// </example>
    /// <typeparam name="TModel">Model</typeparam>
    /// <typeparam name="TProperty">Property of the model</typeparam>
    /// <param name="html">This Html Helper</param>
    /// <param name="propertyExpression">Expression to get property of the model</param>
    /// <param name="editorHtml">Some custom MvcHtmlString to use as the editor field</param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor <TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> propertyExpression,
        IHtmlString editorHtml)
    {
        return html.FormElementFor(propertyExpression,
                                   editorHtml,
                                   html.LabelFor(propertyExpression, new { @class = "control-label" }),
                                   html.ValidationMessageFor(propertyExpression));
    }

    /// <summary>
    ///     Method to build form input with label, editor and validation message.
    /// </summary>
    /// <example>
    ///     <code>
    ///         Html.FormElementFor(model => model.MyProperty, Html.CheckBoxFor(model => model.MyBoolean), Html.DisplayNameFor(model => model.SomeOtherProperty))
    ///     </code>
    /// </example>
    /// <typeparam name="TModel"></typeparam>
    /// <typeparam name="TProperty"></typeparam>
    /// <param name="html"></param>
    /// <param name="propertyExpression"></param>
    /// <param name="editorHtml"></param>
    /// <param name="labelHtml"></param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor <TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> propertyExpression,
        IHtmlString editorHtml,
        IHtmlString labelHtml
        )
    {
        return html.FormElementFor(propertyExpression,
                                   editorHtml,
                                   labelHtml,
                                   html.ValidationMessageFor(propertyExpression));
    }

    /*** EXTRAS ***/

    /// <summary>
    ///     Method to build form input with label, editor and validation message.
    /// </summary>
    /// <example>
    ///     <code>
    ///         Html.FormElementFor(model => model.MyProperty, Html.TextAreaFor)
    ///     </code>
    /// </example>
    /// <typeparam name="TModel">Model</typeparam>
    /// <typeparam name="TProperty">Property of the model</typeparam>
    /// <param name="html">This Html Helper</param>
    /// <param name="expression">Expression to get property of the model</param>
    /// <param name="editor">Editor expression that takes the previous expression parameter and converts it into a MvcHtmlString</param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor <TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> expression,
        Func<Expression<Func<TModel, TProperty>>, MvcHtmlString> editor)
    {
        return FormElementFor(html, expression, editor(expression));
    }

    /// <summary>
    ///     Method to build form input with label, editor and validation message.
    /// </summary>
    /// <example>
    ///     <code>
    ///         Html.FormElementFor(model => model.MyProperty, Html.TextAreaFor, Html.MyDisplayHelper(model => model.MyProperty))
    ///     </code>
    /// </example>
    /// <typeparam name="TModel">Model</typeparam>
    /// <typeparam name="TProperty">Property of the model</typeparam>
    /// <param name="html">This Html Helper</param>
    /// <param name="expression">Expression to get property of the model</param>
    /// <param name="editor">Editor expression that takes the previous expression parameter and converts it into a MvcHtmlString</param>
    /// <param name="labelHtml">Html to use as the label</param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor <TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> expression,
        Func<Expression<Func<TModel, TProperty>>, MvcHtmlString> editor,
        IHtmlString labelHtml)
    {
        return FormElementFor(html, expression, editor(expression), labelHtml);
    }

    /// <summary>
    ///     Method to build form input with label, editor and validation message.
    /// </summary>
    /// <example>
    ///     <code>
    ///         Html.FormElementFor(model => model.MyProperty, Html.TextAreaFor, Html.DisplayFor)
    ///     </code>
    /// </example>
    /// <typeparam name="TModel">Model</typeparam>
    /// <typeparam name="TProperty">Property of the model</typeparam>
    /// <param name="html">This Html Helper</param>
    /// <param name="expression">Expression to get property of the model</param>
    /// <param name="editor">Editor expression that takes the previous expression parameter and converts it into a IHtmlString</param>
    /// <param name="label">Label expression that takes the previous expression parameter and converts it into a IHtmlString</param>
    /// <returns></returns>
    public static MvcHtmlString FormElementFor <TModel, TProperty>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TProperty>> expression,
        Func<Expression<Func<TModel, TProperty>>, MvcHtmlString> editor,
        Func<Expression<Func<TModel, TProperty>>, MvcHtmlString> label)
    {
        return FormElementFor(html, expression, editor(expression), label(expression));
    }

用法:

@Html.FormElementFor(m => m.UserName)
@Html.FormElementFor(m => m.Password, Html.PasswordFor)