#c# #html #asp.net-mvc #razor
#c# #HTML #asp.net-mvc #razor
Вопрос:
Я использую Razor для отображения списка моделей, и конечный пользователь может добавлять или удалять записи в этот список. После нажатия кнопки «Удалить» модель представления возвращается в сообщение контроллера, чтобы удалить запись списка, и возвращается к представлению через return View(model);
. Однако скрытые идентификаторы каждой записи, похоже, только что удалили последнюю строку, а остальные отображаемые строки переместили на единицу вверх, что приводит к повторному заполнению данных с неправильным идентификатором, если в список добавлен другой элемент.
Контроллер генерирует правильные данные, которые были проверены путем проверки параметров в return View(model);
, поэтому проблема в том, что таблица HTML «сохраняет» некоторые значения вместо того, чтобы стирать ее и воссоздавать заново после каждого возврата к представлению.
Другими словами, если первый идентификатор получателя равен 14, а второй равен 20, удаление строки из 14 сначала оставляет отображаемые данные равными 20, но источник представления сообщает, что идентификатор получателя равен 14, и добавление другого элемента изменяет первую строку с 20-х данных на 14 и эти данные. Есть ли способ перезагрузить таблицу и поместить скрытое поле в ту же строку, что и связанные с ним другие данные? Заранее спасибо!
Просмотр модели:
public class NewMailModel
{
public string Title { get; set; }
public string Message { get; set; }
public List<RecipientModel> Recipients { get; set; }
public int CorporateID { get; set; }
public string AddedName { get; set; }
}
RecipientModel:
public class RecipientModel
{
public int RecipientUserID { get; set; }
public string RecipientName { get; set; }
public string RecipientEmail { get; set; }
public bool RemoveRecipient { get; set; }
}
Соответствующий Razor:
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered" id="cTable">
<thead>
<tr>
<th style="display:none"></th>
<th class="text-center">Name</th>
<th class="text-center">E-mail</th>
<th class="text-center">Select</th>
</tr>
</thead>
<tbody>
@if (Model.Recipients.Any())
{
for (var i = 0; i < Model.Recipients.Count; i )
{
<tr>
<td style="display:none">@Html.HiddenFor(m => m.Recipients[i].RecipientUserID)</td>
<td align="center">@Model.Recipients[i].RecipientName</td>
<td align="center">@Model.Recipients[i].RecipientEmail</td>
<td align="center">@Html.CheckBoxFor(m => m.Recipients[i].RemoveRecipient)</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-lg-9">
<button type="submit" id="removeRecipient" class="btn btn-info removeRecipient pull-right" value="Remove Recipient" name="buttonCommand">Remove Selected</button>
</div>
<div class="col-lg-3">
</div>
</div>
Контроллер:
[HttpPost]
public ActionResult NewMail(NewMailModel model, string buttonCommand)
{
if (buttonCommand == "Send")
{
//Miscellaneous code
}
else if (buttonCommand == "Add")
{
//After a removal and subsequent adding, the removed
// RecipientUserID is used here because it was never
// evacuated from the Razor table!!!
RecipientModel added = GetFullRecipient(model.AddedName);
int recipientIndex = -1;
if (model.Recipients != null)
{
recipientIndex = model.Recipients.FindIndex(m => m.RecipientUserID == added.RecipientUserID);
model.Recipients = GetMissingData(model.CorporateID, model.Recipients);
}
else
{
model.Recipients = new List<RecipientModel>();
}
if (recipientIndex == -1)
{
model.Recipients.Add(added);
}
}
else
{
//Remove from list works, but the removed RecipientUserID
// is still hidden in the Razor table and is assigned
// to the next row that moves up into the deleted row's space!!!
if (model.Recipients != null amp;amp; model.Recipients.Count > 0)
{
List<RecipientModel> newRecipients = new List<RecipientModel>();
foreach (var entry in model.Recipients)
{
if (entry.RemoveRecipient == false)
{
RecipientModel mailTo = new RecipientModel
{
RecipientEmail = entry.RecipientEmail,
RecipientName = entry.RecipientName,
RecipientUserID = entry.RecipientUserID,
RemoveRecipient = false
};
newRecipients.Add(mailTo);
}
}
model.Recipients = new List<RecipientModel>();
model.Recipients = newRecipient;
model.Recipients = GetMissingData(model.CorporateID, model.Recipients);
}
else
{
model.Recipients = new List<RecipientModel>();
}
}
return View(model);
}
[HttpGet]
public List<RecipientModel> GetMissingData(int CorporateID, List<RecipientModel> Recipients)
{
DbEntities db = new DbEntities();
var people = db.uspGetUsers(CorporateID).ToList();
for (int i = 0; i < Recipients.Count; i )
{
for (int x = 0; x < people.Count; x )
{
if (Recipients[i].RecipientUserID == people[x].UserID)
{
Recipients[i].RecipientEmail = people[x].UserEmail;
Recipients[i].RecipientName = people[x].UserLastName ", " people[x].UserFirstName;
Recipients[i].RemoveRecipient = false;
break;
}
}
}
return Recipients;
}
Исходный код HTML с 2 строками таблицы:
<tbody>
<tr>
<td style="display:none"><input data-val="true" data-val-number="The field RecipientUserID must be a number." data-val-required="The RecipientUserID field is required." id="Recipients_0__RecipientUserID" name="Recipients[0].RecipientUserID" type="hidden" value="14" /></td>
<td align="center">Simpson, Lisa</td>
<td align="center">email@gmail.com</td>
<td align="center"><input data-val="true" data-val-required="The RemoveRecipient field is required." id="Recipients_0__RemoveRecipient" name="Recipients[0].RemoveRecipient" type="checkbox" value="true" /><input name="Recipients[0].RemoveRecipient" type="hidden" value="false" /></td>
</tr>
<tr>
<td style="display:none"><input data-val="true" data-val-number="The field RecipientUserID must be a number." data-val-required="The RecipientUserID field is required." id="Recipients_1__RecipientUserID" name="Recipients[1].RecipientUserID" type="hidden" value="25" /></td>
<td align="center">Scorpio, Hank</td>
<td align="center">email@gmail.com</td>
<td align="center"><input data-val="true" data-val-required="The RemoveRecipient field is required." id="Recipients_1__RemoveRecipient" name="Recipients[1].RemoveRecipient" type="checkbox" value="true" /><input name="Recipients[1].RemoveRecipient" type="hidden" value="false" /></td>
</tr>
</tbody>
HTML-источник с 1 строкой таблицы после удаления первой строки (обратите внимание, что RecipientUserID — это значение удаленной строки (14), а не отображаемой строки / данных (25)!):
<tbody>
<tr>
<td style="display:none"><input data-val="true" data-val-number="The field RecipientUserID must be a number." data-val-required="The RecipientUserID field is required." id="Recipients_0__RecipientUserID" name="Recipients[0].RecipientUserID" type="hidden" value="14" /></td>
<td align="center">Scorpio, Hank</td>
<td align="center">email@gmail.com</td>
<td align="center"><input checked="checked" data-val="true" data-val-required="The RemoveRecipient field is required." id="Recipients_0__RemoveRecipient" name="Recipients[0].RemoveRecipient" type="checkbox" value="true" /><input name="Recipients[0].RemoveRecipient" type="hidden" value="false" /></td>
</tr>
</tbody>
Комментарии:
1. Поскольку мы не можем видеть, как вы заполняете свою модель или обрабатываете процесс удаления, довольно сложно понять, что может пойти не так. Насколько я вижу, это не проблема в HTML или коде просмотра.
2. Спасибо за комментарий! При проверке значений в ‘return View (model)’ все значения из списка моделей являются точными. Я опубликую правку с кодом контроллера, но похоже, что представление просто отсекает последнюю строку и заполняет только те параметры, которые не скрыты.
3.
model.Recipients = new List<RecipientModel>(); model.Recipients = newRecipient; model.Recipients = GetMissingData(CorporateID, model.Recipients);
. В этих трех строках вы повторно присваиваете свойству «получатели» модели разные значения. Первая строка просто избыточна — нет смысла создавать пустой список, а затем немедленно заменять его другим, уже созданным списком. Это просто пустая трата времени. Также я предполагаю, чтоmodel.Recipients = newRecipient;
это опечатка и она должна бытьnewRecipients;
в конце (отсутствует буква «s»)?4. Вторая и третья строки здесь могут быть проблемой. Во второй строке вы присваиваете свойству model значение списка получателей за вычетом тех, которые вы удалили. Но затем после этого вы немедленно переназначаете свойство так, чтобы оно было любым результатом метода «GetMissingData()» (и я не вижу этого метода, поэтому понятия не имею, что он вернет). Это приведет к перезаписи того, что вы назначили в предыдущей строке. Итак, снова 2-я строка избыточна, просто напишите
model.Recipients = GetMissingData(CorporateID, newRecipients);
и удалите две другие5. Таким образом, это немного упрощает код, но поскольку новый список получателей, который будет передан в ваше представление, получен из результата GetMissingData() , я все еще не могу сказать вам, что не так, не видя этого метода.