Похоже, что вам понадобится код на стороне клиента.
Возможно, что я, возможно, сделаю, поскольку я понимаю вашу потребность, будет иметь скрытый ввод в форме, которую вы обновляете с выбранными друзьями.
Проблема в том, что стандартное кодирование формы не поддерживает иерархические данные, поэтому вам необходимо добавить поддержку для этого вручную. Это не так сложно, как вы увидите, но это хлопот. Это было бы очень просто, если бы вы использовали фреймворк вроде Angular или даже просто отправляли с AJAX в целом. Но это довольно большие изменения, которые, возможно, не стоило бы проходить и реализовывать только для этого случая.
Этот пример зависит от jQuery. Это также супер просто и не поддерживает ничего, как удаление или редактирование существующих друзей. Тем не менее, вы должны просто добавить этот материал. Он также абсолютно не проверяет ни на что, так что сделайте так, как хотите.
var friends = [];
function refreshHiddenField() {
$("#friendsListText").val(friends.map(function(d) { return d.name + "=" + d.age }).join(";"));
}
document.addEventListener("DOMContentLoaded", function(event) {
$("#btnAddFriend").click(function() {
var name = $("#newFriendName").val();
var age = $("#newFriendAge").val();
friends.push({ name : name, age: age });
refreshHiddenField();
var li = $("<li />").text(name + " (" + age + ")");
$("#friendsList").append(li);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- This will actually be an @Html.HiddenFor(m => m.FriendsText), or something -->
<input type="text" id="friendsListText" readonly placeholder="Add some friends first" />
<hr />
<input type="text" id="newFriendName" placeholder="Name" />
<input type="number" id="newFriendAge" placeholder="Age" />
<button type="button" id="btnAddFriend">Add!</button>
<br />
<ul id="friendsList">
</ul>
Как вы увидите, играя с этим (хотя и очень слабо тестируемой), например, добавление друг добавляет детали к пользователю видимый список, и добавляет формат машиночитаемой в вход. В комментарии, этот ввод показан в этом примере, чтобы увидеть, что происходит, но оно не будет в производстве.
Как только вы получили код на стороне клиента, вам просто нужно разобрать скрытое поле при сохранении. Предполагая Friend
класс со свойствами для string Name
и int Age
,
[HttpPost]
public ActionResult EditProfile(User m)
{
// Unrelated stuff
var friends = m.FriendsText.Split(';').Select(c => {
var args = c.Split('=');
return new Friend { Name = args[0], Age = int.Parse(args[1]) };
})
// Use the collection
// Unrelated stuff
}
Это лишь некоторые довольно простые манипуляции с струной LINQ и функция Split
понять машиночитаемый формат от клиента.
Обратите внимание на эту реализацию, что имена не могут иметь точек с запятой или равнозначных знаков.
После того, как вы получили все, распечатать его легко. Просто да, добавьте тип коллекции в свою модель, затем проведите цикл с помощью цикла foreach
.
<ul>
@foreach (var f in Model.FriendsCollection)
{
<li>@f.Name (@f.Age)</li>
}
</ul>
Я знаю, что это не то, что вы говорите, но я предлагаю это как пример того, как вы бы включать в себя коллекцию в модели, согласно первоначальному вопросу.
Я думаю, что это имеет смысл, но я не уверен на 100% того, что вы просите. Что бы вы хотели помочь здесь? Является ли он добавлением свойства массива к классу модели? Это клиентский код, позволяющий динамически вводить данные? Как вложить формы (вы не можете, но мы могли бы найти жизнеспособную альтернативу)? –
Ну, я хочу сделать форму внутри формы. Но если я использую список, подобный приведенному ниже, я не могу назвать правильные переменные. Я могу вызвать model.Name от пользователя, но я не могу назвать model.Name от друга. – bbvanee
Для этого вам нужно будет запустить цикл for в списке и получить доступ к каждому объекту из списка. –