I am building an application that requires a user to answer a survey. I have built the survey to work with questions that are multiple choice questions; however, I am having trouble with doing the same with free-response questions.
This is my form in the view:
@using (Html.BeginForm("Submit", "Survey", FormMethod.Post, new { role = "form" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary("", new { @class = "text-danger" })
var questionNumber = 0;
<h4>Matchmaking Questions</h4>
foreach (var question in Model.Questions)
{
var answers = Model.Answers.Where(a => a.QuestionId == question.Id);
var answerList = new List<Answer>();
<div class="form-group">
<h5>
<i>Q #@(questionNumber + 1)</i>:
@if (question.SurveyId == 3)
{
if (User.IsInRole(UserType.HOST_ROLE))
{
<span>@question.Text</span>
}
else
{
<span>@question.Text2</span>
}
}
else
{
<span>@question.Text</span>
}
</h5>
<!-- If a question has a comment, display it here -->
@if (!question.Comment.IsNullOrWhiteSpace())
{
<h6>@question.Comment</h6>
}
@if (answers.ToList().Any())
{
answerList = answers.ToList();
@Html.DropDownListFor(m => m.UserAnswerIds[questionNumber],
new SelectList(answerList, "Id", "Text"),
"Select your answer", new { @class = "form-control" })
}
else
{
// TextAnswers has the correct number of count here...
// But the values are not updated...
Model.TextAnswers.Add(questionNumber, "");
@Html.TextAreaFor(m => m.TextAnswers[questionNumber], 5, 300, new { })
}
</div>
questionNumber++;
}
<div class="form-group">
<div class="col-md-offset-5 col-md-12">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</div>
}
This is my View Model:
public class SurveyViewModel
{
public IEnumerable<Question> Questions { get; set; }
public IEnumerable<Answer> Answers { get; set; }
public ApplicationUser User { get; set; }
public int[] UserAnswerIds { get; set; }
public Dictionary<int, string> TextAnswers { get; set; }
}
And this is my action that submits the form:
public ActionResult Submit(SurveyViewModel viewModel)
{
var userAnswerIds = viewModel.UserAnswerIds;
var userId = User.Identity.GetUserId();
var surveyComplete = true;
// Create a new answer based on user's text
foreach (var textAnswer in viewModel.TextAnswers)
// viewModel.TextAnswers has count of 0 here...
{
var customAnswer = new Answer()
{
QuestionId = textAnswer.Key,
Text = textAnswer.Value
};
try
{
customAnswer = _context.Answers.Add(customAnswer);
}
catch (Exception e)
{
Console.WriteLine(e);
}
// Add the new custom answer to user's list of answers
userAnswerIds[textAnswer.Key] = customAnswer.Id;
}
// Add each answer to UserAnswer
foreach (var t in userAnswerIds)
{
var currentAnswerBlock = t;
if (_context.Answers.Any(a => a.Id == currentAnswerBlock))
{
var ua = new UserAnswer()
{
ApplicationUserId = userId,
AnswerId = t
};
try
{
_context.UserAnswers.Add(ua);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
else
{
surveyComplete = false;
}
}
// Update user's survey completion status
try
{
_context.Users.Single(u => u.Id == userId).SurveyComplete = surveyComplete;
}
catch (Exception e)
{
Console.WriteLine(e);
}
_context.SaveChanges();
return RedirectToAction("Index", "Profile");
}
The problem I am having is that when I am trying to work with the TextAnswer dictionary within the controller, the dictionary seems to be empty for some reason. When I tried debugging, the dictionary works within the View the "TextAreaFor" method does not seem to be updating the values of the dictionary. However, during the rendering of the view, the dictionary is there and there are entries created for each of the text answers: it's just that the values don't update nor get passed into the controller along with the view model.
I am completely stumped and would love some guidance from professionals.