Answer the question
In order to leave comments, you need to log in
How to pass a specific parameter to an element in a list?
The situation is the following. There is a Model1 which contains a list of another object (Model2) which has a Text property. Tell me how to transfer the form to the Model1 controller, as well as the Model2 list element that should be automatically filled, and the Text property to take the value from the form element.
Model1
public class PollModel
{
public string Id { get; set; }
public string Question { get; set; }
public IEnumerable<Answer> Answer { get; set; }
public int Answered { get; set; }
public string UserIdCreated { get; set; }
}
public class Answer
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; set; }
public string QuestionId { get; set; }
public string Text { get; set; }
public int Chosen { get; set; }
}
public ActionResult Create([Bind(Include = "Id,Question,Answer,Answered,UserIdCreated")] PollModel poll)
{
return View(poll);
}
<div class="form-group">
@Html.LabelFor(model => model.Answer, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer.Single().Text, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer.Single().Text, "", new { @class = "text-danger" })
</div>
</div>
Answer the question
In order to leave comments, you need to log in
Добрый день!
1. Я, возможно, что-то немного не понял, но использовать тип string для поля Id - плохая практика. Используйте int вместо string.
2. Называйте переменные правильно: если у Вас список ответов, то лучше вместо "Answer" назовите Answers" или "AnswerList" - старайтесь писать такой код, чтобы с ним после Вас мог легко работать другой программист.
3. (на всякий случай) Для сообщений валидации можно использовать атрибуты (Required, MaxLength, ...) - я заметил, что в ValidationMessageFor Вы используете "" для текста сообщения валидации.
4. В классе Answer у Вас есть свойство Chosen - если я правильно понимаю, это "Выбран", т.е. это логическая переменная, которая может быть либо "Да", либо "Нет". Зачем используете тип int, ведь есть тип bool?
4. Не знаю, как у Вас, но не заполнив коллекцию Answer(s) в модели PollModel на сервере, Вы не сможете обращаться к ней через Single(), потому что в методе действия Create, который Вы привели, модель не заполняется, соответственно, коллекция Answer(s) равна null, в результате - ошибка, т.к. у null-объекта нельзя обращаться к свойствам. Поэтому Вам нужно как минимум сформировать модель на сервере, например, так:
[HttpGet]
public ActionResult Create()
{
List<Answer> answers = new List<Answer>();
answers.Add(new Answer() { Id = 1, QuestionId = 1, Text = "Вопрос №1", Chosen = false });
PollModel viewModel = new PollModel()
{
Id = "1",
UserIdCreated = "user1",
Answers = answers
};
return View(viewModel);
}
name="Answers[0].Text
и атрибут id="Answers_0__Text"
. Так работает связыватель модели (Model Binder) в ASP.NET MVC по-умолчанию .[HttpGet]
public ActionResult Create()
{
List<Answer> answers = new List<Answer>();
answers.Add(new Answer() { Id = 1, QuestionId = 1, Text = "Вопрос №1", Chosen = false });
PollModel viewModel = new PollModel()
{
Id = "1",
UserIdCreated = "user1",
Answers = answers
};
return View(viewModel);
}
[HttpPost]
public ActionResult Create(PollModel viewModel)
{
TempData["Message"] = String.Format("Текст Вашего вопроса - {0}", viewModel.Answers.First().Text);
return View(viewModel);
}
@using TosterQuestion101113_MVC.Models;
@model PollModel
@{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
<div class="form-group">
@using (Html.BeginForm("Create", "Home", FormMethod.Post, null))
{
if (TempData["Message"] != null)
{
<div class="message">
@TempData["Message"]
</div>
}
@Html.LabelFor(e => e.Answers, new { @class = "control-label col-md-2" })
for (int i = 0; i < Model.Answers.Count(); i++)
{
<div class="col-md-10">
@Html.EditorFor(e => e.Answers[i].Text, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(e => e.Answers.Single().Text, "", new { @class = "text-danger" })
</div>
}
<div>
<input type="submit" value="ОК!" />
</div>
}
</div>
IEnumerable<Answer> Answer
changed to IList<Answer> Answers
- because Ilist provides access to the Count() method to implement the enumeration in a loop Answer.Single().Text
changed to Answers[i].Text
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question