My model:
public class EmployeeModel
{
[Required]
[StringLength(50)]
[Display(Name = "Employee Name")]
public string EmpName { get; set; }
[Required]
[StringLength(150)]
[Display(Name = "Email Id")]
public string Email { get; set; }
[Required]
[Range(18, 150)]
public int Age { get; set; }
}
In my view:
@Html.MyEditFor(model=>model.EmpName)
@Html.MyEditFor(model=>model.Email)
@Html.MyEditFor(model=>model.Age)
My custom helper:
public static MvcHtmlString MyEditFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, object>> expression)
{
var partial = html.Partial("Item", new LabelEditorValidation() { Label = html.LabelFor(expression), Editor = html.EditorFor(expression), Validation = html.ValidationMessageFor(expression) }).ToString();
return MvcHtmlString.Create(partial);
}
Item.cshtml - partial view:
@model MyClientCustomValidation.Models.LabelEditorValidation
<tr>
<td class="editor-label" style="border: 0;">
@Model.Label
</td>
<td class="editor-field" style="border: 0">
@Model.Editor
@Model.Validation
</td>
</tr>
LabelEditorValidation - model for Item.cshtml:
public class LabelEditorValidation
{
public MvcHtmlString Validation { get; set; }
public MvcHtmlString Label { get; set; }
public MvcHtmlString Editor { get; set; }
}
I have exception
Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions
on line:
var partial = html.Partial("Item", new LabelEditorValidation() { Label = html.LabelFor(expression), Editor = html.EditorFor(expression), Validation = html.ValidationMessageFor(expression) }).ToString();
The exception occures when @Html.MyEditFor
is called for model.Age
.
@Html.MyEditFor(model=>model.Age)
But it not occures when @Html.MyEditFor
is called for model.EmpName
and model.Email
.
That's because model.EmpName
and model.Email
are strings but model.Age
is int
For the Google search users,
Just don't call any Html.XyzFor
methods like this
@Html.CheckBoxFor(model => model.Property***.MyMethod()***)
Use view models
instead, to apply that MyMethod
on the given property.
You could make your helper a little more generic and get rid of the object
argument:
public static MvcHtmlString MyEditFor<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty>> expression
)
{
var partial = html.Partial(
"Item",
new LabelEditorValidation
{
Label = html.LabelFor(expression),
Editor = html.EditorFor(expression),
Validation = html.ValidationMessageFor(expression)
}
).ToString();
return MvcHtmlString.Create(partial);
}
Now your expression won't break as there won't be unnecessary boxing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With