Добрый день!
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);
}
5. Т.к. у Вас коллекция Answer(s), то для правильной привязки нужно правильно сформировать View, потому что привязка к коллекциям в ASP.NET MVC осуществляется особым образом - если посмотрите на html-код, то увидите, что тег input, в который нужно ввести текст, имеет атрибут
name="Answers[0].Text
и атрибут
id="Answers_0__Text"
. Так работает связыватель модели (Model Binder) в ASP.NET MVC по-умолчанию .
Рабочий пример - основан на шаблоне ASP.NET MVC 4 Internet Application в VS 2012:
HomeController.cs:
[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);
}
Create.cshmtl:
@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>
Замечания:
1. Свойство
IEnumerable<Answer> Answer
изменено на
IList<Answer> Answers
- потому, что Ilist предоставляет доступ к методу Count() для реализации перечисления в цикле
2.
Answer.Single().Text
изменено на
Answers[i].Text
3. И вообще - у меня сложилось впечатление, что Вы начали недавно изучать ASP.NET MVC и в том числе не так давно программируете. Поэтому я вынужден настаивать: читайте от корки до корки книгу "ASP.NET MVC3 (либо 4) Framework с примерами на C# для профессионалов" - там всё просто отлично объяснен ASP.NET MVC.
Надеюсь, я Вам немного помог.
Успехов!