C# 为视图模型中的所有属性生成标签、文本框和验证消息
我有一个视图,在该视图中,我发现自己对视图模型中的所有属性重复相同的代码,如下所示: 查看C# 为视图模型中的所有属性生成标签、文本框和验证消息,c#,asp.net,asp.net-mvc,asp.net-mvc-4,asp.net-mvc-5,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.Pa
@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.htmlhelp,System.Linq.Expressions.Expression>)的类型参数
我在谷歌上搜索过这个问题,但找不到一个好的解决方案。快速回答是肯定的,有。您只需覆盖对象
模板,然后在那里迭代模型属性,将它们发送到另一个模板,该模板将生成您所需的所有元素
1-为整个模型
调用编辑器
帮助程序(您希望在其中呈现所有属性):
2-迭代属性(在Object.cshtml
中):
3-构建所有元素(在Template.cshtml
中):
您可以在模型字段上使用
UIHint
来简化它,如下所示:
型号:
public class UserModel
{
[UIHint("UserModelField")]
public string Username { get; set; }
[UIHint("UserModelField")]
public string Password { get; set; }
}
EditorTemplateUserModelField.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);
}
或者,您也可以编写一个HTML帮助程序来为您执行此操作: (所有方法都返回到第一个方法,因此如果要将结果包装到DIV左右,只需更改第一个实现) 用法:
@Html.FormElementFor(m => m.UserName)
@Html.FormElementFor(m => m.Password, Html.PasswordFor)
这就像试图用一个工具为你设计一个网页,不是吗?@Leo我不明白你的话。我试图避免双重代码,成为一名更好的开发人员。我不是在要求一个工具,我希望能够编写这个工具。脚手架不起作用吗?使用“EditorFor”来渲染标签,这样做是否有点违背EditorTemplate的想法?@Moeri我想说不是,它简化了每次在视图中重新输入标签的过程。您可以在对象级别执行此操作,但这仍然意味着您将为每个字段重复标签、文本框和验证消息,并且仅限于该模型对象。因此,无论如何,您都希望它们出现在编辑器模板中。
@model string
@Html.LabelFor(m => m)
@Html.TextBoxFor(m => m)
@Html.ValidationMessageFor(m => m)
@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);
}
/// <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)