Я проверил MVC post a list of complex objects, а также https://mhwelander.net/2014/03/26/asp-net-mvc-model-binding-not-occurring-when-posting-list-of-complex-types/ и еще несколько сообщений по этому вопросу.MVC 5 и список сложного типа
Я бы предпочел задать вопрос, чтобы понять, а не просто скопировать вставить ответ.
У меня есть сложный тип, как показано ниже:
public interface ICaracteristic
{
int value { get; set; }
int max { get; set; }
string name { get; set; }
}
public class BaseAttributes : ICaracteristic
{
public int max { get; set; }
public int value { get; set; }
public string name { get; set; }
Random r = new Random();
}
и объект, используя список кратные этих типов:
public class Character
{
// Infos
public string characterName { get; set; }
public string playerName { get; set; }
public IGame game { get; set; }
// Caracteristics
public List<ICaracteristic> baseAttr { get; set; }
public List<ICaracteristic> skills { get; set; }
public List<ICaracteristic> stats { get; set; }
public List<ICaracteristic> spendPoints { get; set; }
}
Я избавлю вас конструкторы и несколько других методов.
Теперь, для создания, я просто прошу моего пользователя ввести имена персонажа и игрока, без проблем, он отлично работает, поскольку это простые строки.
Для редактирования я получаю символ в «моей БД» (на основе XML-листов, но это здесь не имеет значения), а также отображать его таким образом:
@model RPGmvc.Models.Character
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<h4>Character @Html.TextBoxFor(model => model.characterName)</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="row">
<!--SECTION BASE ATTRIBUTES-->
<div class="col-md-3">
<!-- @foreach (var item in Model.baseAttr)
{
<div>
<label>@Html.DisplayFor(model => item.name)</label>
<p>@Html.EditorFor(model => item.value, new { @class = "form-control" })</p>
</div>
}
Для отображения, это работает отлично: он показывает правильные имена и значения каждого базового атрибута моего символа (а также значения других списков).
Однако, когда я нажимаю кнопку «Сохранить» под формой, отправленная модель обновляет значения этого списка ... но не имя_им.имя.
Что странно, так это то, что он смешивает разные конструкторы этой модели: имя игрока, которое я не использую в моем шаблоне редактирования, имеет значение «toby defined» (как в моем пустом базовом конструкторе), но characterName является одним из текущего редактируемого символа вместо «нового символа» (как в указанном конструкторе)
Я попытался использовать for вместо foreach, полагая, что, возможно, индекс в списке поможет для передачи правильных значений; но поскольку я использую интерфейс, который дал ошибку «Не удалось создать экземпляр интерфейса».
Я пробовал с помощью специального редактора, но он создал ту же проблему, что и «foreach».
(Вот пользовательский редактор, на всякий случай:
@model RPGmvc.Models.Caracteristic.ICaracteristic
<p>
@Html.DisplayFor(m => m.name)
@Html.DisplayFor(m => m.value)
</p>
Обратите внимание, что с помощью интерфейса в качестве модели не вызывает никаких проблем.)
Я понимаю, что я мог бы, видимо, добавить очень много аннотаций на моей странице, чтобы отсортировать это, но так как пользовательский редактор не работал и не использовал индекс с индексом, мне сначала хотелось бы объяснить, что происходит:
Что происходит с вставкой модели здесь? Мог ли я «заставить» его создать экземпляр реализации моего интерфейса, а не самого интерфейса? Почему HttpPost создает настраиваемый объект, смешивающий мои конструкторы?
Благодарим за помощь.
Edit: Стивен Muelcke помог мне, советуя, чтобы удалить интерфейсы из моей модели и с использованием реальных реализаций.Это почти сработало:
Теперь мой пост принимает правильные значения BaseAttributes, но имена этих имен «null». Это проблематично, так как мой Datas приходит из XML-листов, в которых я ищу этот путь:
foreach (ICaracteristic battr in myCharac.baseAttr)
{
var currentNode = myDoc.SelectSingleNode("/character_sheet/base_attributes/" + battr.name.Replace(" ", "_").ToLower());
currentNode.InnerText = battr.value.ToString();
}
Который явно терпит неудачу, так как имя «нуль».
Я только сделал изменение от «foreach» до «for» в разделе «Базовые атрибуты». В этом разделе все имена имеют значение null. В других разделах значения не принимаются.
Любая идея?
Вы не можете привязываться к intefaces ('DefaultModelBinder' не может инициализировать экземпляр интерфейса). И вам нужен цикл 'for' (или пользовательский' EditorTemplate') - цикл 'foreach' не будет работать - см. [Этот ответ] (http://stackoverflow.com/questions/30094047/html-table-to-ado -сетью-DataTable/30094943 # 30094943). Вы можете создать пользовательский 'ModelBinder' для работы с интерфейсами, но вам также нужно будет опубликовать значения, указывающие, какая конкретная реализация инициализируется –
@StephenMuecke Итак, если я заменил« List baseAttr »в моей модели символов« Список baseAttr ", он должен работать? –
DoctorPrisme
Да, если вы используете цикл 'for' (или пользовательский' EditorTempate' для типа 'BaseAttributes' и в основном представлении используйте' @ Html.EditorFor (m => m.baseAttr) ' –