Reputation: 4752
I created an editor template to display text boxes included in a form.
@model WebApplication1.Models.PersonViewModel
<input type="text" class="form-control" name="@ViewData.TemplateInfo.HtmlFieldPrefix" value=""/>
I simply want to include the 'form-control' class in all my input text boxes used to collect data for this model.
public class PersonViewModel
{
[UIHint("_TextFormControl")]
public string FirstName { get; set; }
[UIHint("_TextFormControl")]
public string LastName { get; set; }
public int Age { get; set; }
}
This works great when the form starts out blank, however, when I use the template for forms pre-populated with data, like when I want to edit an existing model, I get the error message: "The model item passed into the dictionary is of type 'System.String', but this dictionary requires a model item of type 'WebApplication1.Models.PersonViewModel'."
Here is my controller:
// GET: /Person/Edit/5
[HttpGet]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Person person = db.Persons.Find(id);
if (person == null)
{
return HttpNotFound();
}
return View(person);
}
How do I allow this editor to be used with existing data, as well as new forms?
Upvotes: 0
Views: 1850
Reputation:
You have created an EditorTemplate
for typeof PersonViewModel
but your use of [UIHint("_TextFormControl")]
applied to typeof string
means your passing string
to the template, not PersonViewModel
. Its unclear exactly what your trying to achieve here but based on your current model, he template needs to be
@model String
@Html.TextBox("") // or @Html.TextBoxFor(m => m)
However this is just the same as using @Html.EditorFor(m => m.FirstName)
(or TextBoxFor()
) in the view. One reason you might do something like this is generate multiple html elements, for example
@model String
@Html.Label("")
@Html.TextBox("")
@Html.ValidationMessage("")
so that using @Html.EditorFor(m => m.FirstName)
in the main view would generate the label, textbox and placeholder for validation messages.
But one of the real benefits of using custom editor templates is when you use them for complex types and want a consistent UI for those types. For example, you can create a template for typeof PersonViewModel
. In /Views/Shared/EditorTemplates/PersonViewModel.cshtml
(note that the name of the template must match the name of the type)
@model WebApplication1.Models.PersonViewModel
<div>
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
@Html.ValidationMessageFor(m => m.FirstName)
</div>
<div>
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
@Html.ValidationMessageFor(m => m.LastName)
</div>
.... // ditto for other properties of PersonViewModel
Then in the main view
@model WebApplication1.Models.PersonViewModel
@Html.EditorFor(m => m)
This will also work for a collection of PersonViewModel
and generate one editor template for each PersonViewModel
in the collection
@model IEnumerable<WebApplication1.Models.PersonViewModel>
@Html.EditorFor(m => m)
Similarly, if you had another model that contained a property public PersonViewModel Person { get; set; }
, you can use @Html.EditorFor(m => m.Person)
Side note:
PersonViewModel
to your
view in the 'Create' method which is poor practice. Your controller
method should pass an instance to the view.value
attribute. In
addition you do not add the data-val-*
attributes used for client
side validation. Always use the strongly typed html helpers to
generate your html so you get correct 2-way model binding and take
advantage of all the built-in features of MVC.Upvotes: 1