#c# #asp.net-core-mvc #razor-pages
Вопрос:
У меня возникла проблема с захватом модели, когда она передается из представления в контроллер. В принципе, у каждого вопроса есть набор ответов на вопросы (думайте об этом как о списке предлагаемых ответов на определенный вопрос в раскрывающемся списке). ClinicalSummaryAnswer-это структура, содержащая один ответ на вопрос для данного пользователя. Таким образом, пользователь получает коллекцию ClinicalSummaryAnswer, где каждый элемент является ответом на ответ.
Когда я отправляю форму ниже, все элементы в модели ClinicalSummaryView (ClinicalSummaryAnswer, Вопросы, ответы на вопросы) со стороны контроллера являются нулевыми. Есть какие-нибудь идеи, почему это может произойти? Я подозреваю, что это может быть связано с foreach? Я не уверен. Пожалуйста, помогите!!
Мой Взгляд
@model TissueBankApp.Models.View.ClinicalSummaryView
<div>
@using (Html.BeginForm("Create", "ClinicalSummary", FormMethod.Post, new { @class = "form-horizontal" }))
{
<div class="form-group">
<input type="hidden" asp-for="Person.PersonId" value="Person.PersonId" />
<input type="submit" value="Create" class="btn btn-outline-primary btn-sm" />
<a asp-action="Details" asp-controller="Person" asp-route-id="Person.PersonId" class="btn btn-outline-primary btn-sm">Cancel</a>
</div>
<div class="col-md-12">
<div class="form-row">
<b> @Html.DisplayFor(model => model.ClinicalSummary.Description) </b>
</div>
@foreach (var question in Model.Questions) //For every question, generate question, and generate responses
{
<div class="form-row">
<label class="control-label col-md-4">@question.QuestionText</label>
@if (question.QuestionResponse.Count() != 0) //If count ViewData[QID] != 0, generate select dropdown, otherwise, input.
{
@Html.DropDownListFor(n => n.ClinicalSummaryAnswer.FirstOrDefault(m => m.QuestionId == question.QuestionId).AnswerId, new SelectList(question.QuestionResponse, "ResponseId", "ResponseText"), "", new { @class = "form-control col-md-4" })
}
else
{
@Html.TextBoxFor(n => n.ClinicalSummaryAnswer.FirstOrDefault(m => m.QuestionId == question.QuestionId).OtherText, new { placeholder = "", @class = "form-control col-md-4", @type = "date" });
}
</div>
}
</div>
}
</div>
Контроллер
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ClinicalSummaryView viewModel, string[] AnswerId, string[] OtherText)
{
//STUFF
//Ignore the OtherText, and AnswerId. I was testing to see if these are passed from view to controller and they are indeed. I just have no way of identifying which answer belongs to which question.
}
Комментарии:
1. как ваш контроллер переходит
model
кview
?2. Ты имеешь в виду наоборот? [HttpPost] [ValidateAntiForgeryToken] публичная асинхронная задача<IActionResult> Создать(ClinicalSummaryView ViewModel, строка[] AnswerId, строка[] Другой текст) { //МАТЕРИАЛ } Интересная вещь заключается в том, что другой текст заполняется списком строк из полей ввода, а идентификатор ответа заполняется списком идентификаторов ответов, выбранных из раскрывающегося списка. Я просто проверял это, потому что, когда я проверял элемент в браузере, все поля ввода/выбора имели одинаковое «имя» (другой текст и идентификатор ответа)
3. ваш вопрос содержит слишком много информации о шуме, можете ли вы удалить их, чтобы они были минимальными?
4. Я отредактировал код в представлении, чтобы он содержал только необходимую информацию. Так лучше? Или вступление было слишком длинным? Я просто пытался объяснить структуру модели, чтобы понять, могу ли я неправильно привязывать элементы @Html.
Ответ №1:
Во-первых,вам нужно знать, что для каждого свойства сложного типа привязка модели просматривает источники для шаблона имени prefix.property_name
. Если ничего не найдено, он ищет просто property_name
без префикса.Ваш сервер хочет получить ClinicalSummaryView.ClinicalSummaryAnswer
модель списка. так что то, что вы проходите, должно быть ClinicalSummaryAnswer[index].PropertyName
.
Измените, как показано ниже:
@using (Html.BeginForm("Create", "Home", FormMethod.Post, new { @class = "form-horizontal" }))
{
<div class="form-group">
<input type="hidden" asp-for="Person.PersonId" value="@Model.Person.PersonId"/>
<input type="submit" value="Create" class="btn btn-outline-primary btn-sm" />
<a asp-action="Details" asp-controller="Person" asp-route-id="@Model.Person.PersonId" class="btn btn-outline-primary btn-sm">Cancel</a>
</div>
<div class="col-md-12">
<div class="form-row">
<b> @Html.DisplayFor(model => model.ClinicalSummary.Description) </b>
</div>
@{ var i = 0;} //add here...
@foreach (var question in Model.Questions)
{
<div class="form-row">
<label class="control-label col-md-4">@question.QuestionText</label>
@if (question.QuestionResponse.Count() != 0)
{
//change here....
@Html.DropDownList("ClinicalSummaryAnswer[" i "].AnswerId", new SelectList(question.QuestionResponse, "ResponseId", "ResponseText"), new { @class = "form-control col-md-4" })
}
else
{
//change here....
@Html.TextBox("ClinicalSummaryAnswer[" i "].OtherText",null, new { placeholder = "", @class = "form-control col-md-4", @type = "date" });
}
</div>
i ; //add here...
}
</div>
}
Кроме того, необходимо изменить следующий код:
//change the value
<input type="hidden" asp-for="Person.PersonId" value="@Model.Person.PersonId"/>
<input type="submit" value="Create" class="btn btn-outline-primary btn-sm" />
//change asp-route-id here..
<a asp-action="Details" asp-controller="Person" asp-route-id="@Model.Person.PersonId" class="btn btn-outline-primary btn-sm">Cancel</a>
Комментарии:
1. Мне не нужен текст вопроса (который находится в метке) для передачи. Мне нужны значения выбранных параметров в раскрывающемся списке и значения в разных текстовых полях для передачи (Модель. Клинический ответ на вопрос , который является коллекцией). Я думаю, что ваша модификация не решает эту проблему. Поправьте меня, если я ошибаюсь.
2. Привет @HK1232, похоже, вы не хотите
string[] AnswerId, string[] OtherText
получать данные, вы хотите получать данные раскрывающегося списка и текстовогоClinicalSummaryView viewModel
поля . Пожалуйста, проверьте мой обновленный ответ.3. Привет, Рена, спасибо за помощь. Извините, я забыл проверить поток, я решил проблему, у меня уже был ClinicalSummaryView ViewModel в качестве аргумента изначально, но все это было равно нулю. Мне удалось настроить его (у меня нет кода перед банкоматом). Спасибо за помощь, несмотря ни на что!
4. Привет @HK1232, Если мой ответ поможет вам решить вашу проблему,не могли бы вы принять его в качестве ответа? См.: Как принять в качестве ответа . Спасибо.