У меня есть модель, которая имеет сложный тип как свойство. Я создал пользовательский DisplayEditor для сложного типа дочернего элемента, и он корректно связан с загрузкой страницы. Когда страница публикуется после внесения изменений, тип Dependents устанавливается равным null. Вот код для модели Сотрудника, который представляет ребенка иждивенцы свойство:Custom EditorTemplate не возвращает значения формы Правильно
[Display(Name = "Dependents")]
[DataType(DataType.MultilineText)]
public List<Dependent> Dependents { get; set; }
Вот Зависимая модель:
[Serializable]
public class Dependent : Person
{
public Dependent()
{
Deduction deduction = new Deduction(this) { Amount = Constants.DependentDeductionAmount };
this.Deduction = deduction;
}
[Key]
[HiddenInput(DisplayValue = false)]
public int DependentId { get; set; }
[Required]
[Display(Name = "Dependent Type")]
public DependentType DependentType { get; set; }
[Required]
public override double DeductionAmount => Constants.DependentDeductionAmount;
}
Методы действий 2 редактирования на контроллере сотрудника (я пробовал TryUpdateModel , не работает):
public ViewResult Edit(int employeeId)
{
if (employeeId < 0) throw new ArgumentOutOfRangeException(nameof(employeeId));
Employee employee = _employeeRepository.Employees.FirstOrDefault(e => e.EmployeeId == employeeId);
bool result = TryUpdateModel(employee, new FormValueProvider(ControllerContext));
return View(employee);
}
[HttpPost]
public ActionResult Edit(Employee employee)
{
if (employee == null) throw new ArgumentNullException(nameof(employee));
if (ModelState.IsValid)
{
employee.Changed = true;
employee.Dependents.ForEach(d => d.Changed = true);
_employeeRepository.SaveEmployee(employee);
TempData["message"] = $"{employee} has been saved.";
return RedirectToAction("Index");
}
else {
// there is something wrong with the data values
return View(employee);
}
}
Вот Edit.cshtml:
@model Paylocity.HR.Domain.Entities.Employee
@{
ViewBag.Title = $"{"Edit"} {Model}";
}
<div class="panel panel-default">
<div class="panel-heading">
<h3>@ViewBag.Title</h3>
</div>
@using (Html.BeginForm("Edit", "Employee"))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr/>
@Html.ValidationSummary(true, "", new {@class = "text-danger"})
<h4>Employee</h4>
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.FirstName, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.LastName, "", new {@class = "text-danger"})
</div>
</div>
<hr/>
@Html.EditorFor(model => model.Dependents, "Dependents")
@Html.HiddenFor(model => model.EmployeeId)
</div>
<div class="panel-footer">
<input type="submit" value="Save" class="btn btn-primary"/>
@Html.ActionLink("Cancel and return to List", "Index", null, new {@class = "btn btn-default"})
</div>
}
</div>
Вот Dependent.cshtml EditorTemplate:
@model IEnumerable<Dependent>
@using Paylocity.HR.Domain.Entities
@foreach (var dep in Model)
{
<h4>Dependent</h4>
<div class="form-group">
@Html.LabelFor(m => dep.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(m => dep.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => dep.FirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => dep.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(m => dep.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => dep.LastName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => dep.DependentType, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(m => dep.DependentType, new { @class = "form-control" })
@Html.ValidationMessageFor(m => dep.DependentType, "", new { @class = "text-danger" })
</div>
</div>
<hr />
}
объект Сотрудник связывает правильно и изменяемым, это только тип иждивенцы ребенок, который не связан правильно. HTML отображает правильные идентификаторы/имена полей зависимой формы (я верю?). Нужно ли мне реализовать какой-то пользовательский код связующего, или я пропущу что-то очевидное здесь?
Это мой первый вопрос о СО, надеюсь, я предоставил достаточно информации.
Мне показалось, что я уже пробовал этот подход (изменяя EditorTemplate, чтобы не использовать коллекцию, и привязывать непосредственно к коллекции в основном представлении), но, видимо, я этого не сделал или пропустил что-то в этом процессе. Это ответ, я знал, что это будет что-то простое. Спасибо! –