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