#c# #asp.net-core-mvc
#c# #asp.net-core-mvc
Вопрос:
Привет, ребята, я все еще новичок в Asp.net и C #. Я пишу систему управления, контролирующую деятельность office. Я столкнулся с проблемой, когда я передаю объект ViewModel, который содержит список, регистр и значение int, в представление из контроллера. Если вновь созданный case имеет тот же идентификатор, он вернет тот же объект ViewModel обратно в POST-контроллер, но когда объект передается из view в post-контроллер, каждый объект list равен null, за исключением примитивных типов и Case . Я не понимаю, почему передается один и тот же объект, но когда он передается контроллеру из представления, весь список, который только что использовался для заполнения html, равен нулю, это из-за инъекции или просто из-за того, как работает привязка модели? Большое спасибо
В представлении просто есть цикл for, отображающий каждый элемент в TopTenList. вверху есть оператор привязки @model. Вот представление
@model LabManager.InputModels.CaseInputModel
@inject LabManager.Data.ApplicationDbContext _dbContext
@using LabManager.ModelExtensions
@{
ViewData["Title"] = "Overview";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@section Stylesheet{
<link rel="stylesheet" href="~/css/Case/index.css" />
}
<div id="home-view">
<div class="card">
<div class="card-header">
<a class="card-link" data-toggle="collapse" href="#topTen">
Top Ten Priority Cases
</a>
</div>
<div id="topTen" class="collapse show" data-parent="#home-view">
<div class="card-body">
<table class="table">
<thead>
<tr>bunch of names</tr>
</thead>
<tbody>
@{int i = 1;}
@foreach (var item in Model.TopTenList)
{
show somethings.
}
Вот контроллер.
public ActionResult Create(int setPriority)
{
CaseInputModel input = new CaseInputModel {
SelectedPriority = setPriority,
};
input.SetTopTenList(_dbContext);
return View(input);
}
// POST: Takes info from the input model and creates a new case in the db
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CaseInputModel inputs)
{
//if case id already exist in the database, return view()
if (DbContext.Cases.Any(m => m.CaseId == inputs.NewCase.CaseId))
{
inputs.ErrorMessage = "Error: Case ID already exists";
return View(inputs);
}
Ее модель:
public class Case
{
[Required]
[RegularExpression("[^0-9]")]
public int Id { get; set; }
public int CaseId { get; set; }
public Status Status { get; set; }
public string Notes { get; set; }
}
Вот CaseInputModel(объект ViewModel)
public class CaseInputModel
{
public CaseInputModel()
{
NewCase = new Case();
RegularCaseList = new List<Case>();
}
public string ErrorMessage { get; set; }
public int SelectedPriority { get; set; }
public Case NewCase { get; set; }
public List<Case> RegularCaseList { get; set; }
public List<Case> TopTenList { get; set; }
public void SetTopTenList(ApplicationDbContext dbContext)
{
TopTenList = PriorityNodeExtensions.ToSortedList(dbContext.TopTens,
dbContext);
}
Комментарии:
1. Не могли бы вы поделиться своей моделью и представлением razor? И причина, по которой ваше представление заполняет нулевой объект, заключается в том, что объект имеет значение null при отправке на контроллер. И когда вы возвращаете view с model, он будет отображать нулевые данные в html.
2. Я добавлю это. Вы правы в том, что когда он отправляется на контроллер. Запрос get к контроллеру возвращает представление (ввод), в котором содержится список топ10 случаев. Но когда он передается обратно из представления в post controller, сохраняются только 2 атрибута объектов (Case, int), остальные равны нулю.
3. То, что вы предоставили, не помогает воспроизвести вашу проблему. Вам необходимо предоставить представление rest razor о том, как вы моделируете привязку. И вы могли бы получить только Case и int, пожалуйста, сообщите нам конкретное имя свойства двух объектов в InputModel. В вашем коде есть некоторые errors:1.In вы получаете метод, вы возвращаете входную модель, но вашему представлению razor требуется IEnumerable<Case> , вы пропустили другое представление razor? 2.In в вашем методе get вы устанавливаете только два значения свойства, убедитесь, что ваш razor view имеет HTML-код других свойств и заполняет данные, в противном случае вы не смогли бы передать все данные контроллеру.
4. @Rena, Привет, я прошу прощения за то, что не ответил раньше. На самом деле у меня все еще есть проблема. Я обновлю свой вопрос, пытаясь получить больше изображений. Большое спасибо за продолжение.
Ответ №1:
Во-первых, вам нужно знать, что для каждого свойства сложного типа привязка модели просматривает источники для шаблона имени prefix.property_name
. Если ничего не найдено, он ищет только property_name
без префикса.
Ссылка:
Вот простая демонстрация о том, как передать данные контроллеру:
Вид:
@model InputModel
<form asp-action="Create">
<table class="table">
<thead>
<tr>bunch of names</tr>
</thead>
<tbody>
<tr>
<td>SelectedPriority</td>
<td><input asp-for="@Model.SelectedPriority" /></td>
</tr>
<tr>
<td>New Case</td>
<td><input asp-for="@Model.NewCase.Id" /></td>
<td><input asp-for="@Model.NewCase.CaseId" /></td>
<td><input asp-for="@Model.NewCase.Notes" /></td>
</tr>
@{int i = 0;}
@foreach (var item in Model.TopTenList)
{
<tr>
<td>TopTenList_@i</td>
<td><input name="TopTenList[@i].Id" asp-for="@item.Id" /></td>
<td><input name="TopTenList[@i].CaseId" asp-for="@item.CaseId" /></td>
<td><input name="TopTenList[@i].Notes" asp-for="@item.Notes" /></td>
</tr>
i ;
}
</tbody>
</table>
<input type="submit" value="create" />
</form>
Результат:
Обновить:
возврат view с model он может успешно отобразить модель, но вы не смогли отобразить TopTenList.Убедитесь, что вы создали входные данные для свойств модели и отладили действие, чтобы проверить, передали ли вы TopTenList методу post.Если вы только визуализируете данные, используя @Model.Property
их, они не будут переданы на серверную часть.
Вид:
@model CaseInputModel
<form asp-action="Create">
<table class="table">
<thead>
<tr>bunch of names</tr>
</thead>
<tbody>
@if (Model.ErrorMessage != null)
{
@Model.ErrorMessage
}
<tr>
<td>SelectedPriority</td>
<td><input asp-for="@Model.SelectedPriority" /></td>
</tr>
<tr>
<td>New Case</td>
<td><input asp-for="@Model.NewCase.Id" /></td>
<td><input asp-for="@Model.NewCase.CaseId" /></td>
<td><input asp-for="@Model.NewCase.Notes" /></td>
</tr>
@{int i = 0;}
@foreach (var item in Model.TopTenList)
{
<tr>
<td>
@item.Id
<input name="TopTenList[@i].Id" asp-for="@item.Id" hidden />
</td>
<td>
@item.CaseId
<input name="TopTenList[@i].CaseId" asp-for="@item.CaseId" hidden />
</td>
<td>
@item.Notes
<input name="TopTenList[@i].Notes" asp-for="@item.Notes" hidden />
</td>
</tr>
i ;
}
</tbody>
</table>
<input type="submit" value="create" />
</form>
Результат:
Комментарии:
1. Возможно, я не очень хорошо объяснил проблему. Пожалуйста, потерпите меня. Страница создания работает нормально регулярно, заполните toptenlist в методе Create Controller и передайте его в представление. Однако, если я введу тот же идентификатор обращения #, который уже есть в базе данных, он вернет тот же вид той же ViewModel с сообщением об ошибке, это вызывает проблему, поскольку это «обновит» страницу, и TopTenList будет потерян. Когда вызывается метод Get Create, он создает TopTen и переходит к представлению. Представление заполняет все и передает тот же объект ViewModel обратно в метод HTTP Create .
2. Теперь, когда метод http создает get эту ViewModel, в данном случае «input». он имеет только приоритет переменной int, объект case, а toptenlist равен null. таким образом, когда этот ввод затем возвращается в представление, toptenlist не может быть заполнен, поскольку он равен null.
3. Привет @HeChuan, извините за поздний ответ. Пожалуйста, проверьте мой обновленный ответ.