1

When I try and pass the data from the view to the controller, the parameters in debug mode show up as null when defined as a List (In the save method).

Here is the method in the controller that is getting the exception when trying to save data. When they were just objects (Category category instead of List< Category > category) they were returning the first instance of data, but weren't null).

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(Survey survey, List<Category> category, List<Question> question, List<Answer> answer)
    {
        if (survey.SurveyId == 0)
        { 
            _context.Surveys.Add(survey);
            foreach (var categorytoAdd in category)
                _context.Categories.Add(categorytoAdd);
            foreach (var questiontoAdd in question)
                _context.Questions.Add(questiontoAdd);
            foreach (var answertoAdd in answer)
                _context.Answers.Add(answertoAdd);
        }
        else
        {
            foreach (var surveyInDb in _context.Surveys.Where(m => m.SurveyId == survey.SurveyId))
                surveyInDb.Description = survey.Description;

            //old code before switching to a list

            //foreach (var categoryInDb in _context.Categories.Where(m => m.CategoryId == category.CategoryId))
            //categoryInDb.CategoryDescription = category.CategoryDescription;

            //foreach (var questionInDb in _context.Questions.Where(m => m.QuestionId == question.QuestionId))
            //    questionInDb.QuestionText = question.QuestionText;

            //foreach (var answerInDb in _context.Answers.Where(m => m.AnswerId == answer.AnswerId))
            //    answerInDb.AnswerText = answer.AnswerText;

            foreach (var categorytoAdd in category)
            {
                foreach (var categoryInDb in _context.Categories.Where(m => m.CategoryId == categorytoAdd.CategoryId))
                    categoryInDb.CategoryDescription = categorytoAdd.CategoryDescription;
            }

            foreach (var questiontoAdd in question)
            {
                foreach (var questionInDb in _context.Questions.Where(m => m.QuestionId == questiontoAdd.QuestionId))
                    questionInDb.QuestionText = questiontoAdd.QuestionText;
            }

            foreach (var answertoAdd in answer)
            {
                foreach (var answerInDb in _context.Answers.Where(a => a.AnswerId == answertoAdd.AnswerId))
                    answerInDb.AnswerText = answertoAdd.AnswerText;
            }
        }
        _context.SaveChanges();
        return RedirectToAction("Index", "Surveys");
    }

And the view that the data is being sent from. I'm looping through all the categories, questions in the categories, and answers for the questions. I'm not even sure if I actually need the HiddenFields here.

@using (Html.BeginForm("Save", "Surveys"))
{

<div class="form-group">
    @Html.LabelFor(s => s.SurveyId)
    @Html.TextBoxFor(s => s.Description, new { @class = "form-control" })
    @Html.ValidationMessageFor(s => s.Description)
</div>
<div id="Survey" class="form-group">
    @foreach (var category in Model.Categories.Where(c => c.SurveyId == Model.SurveyId))
    {
        <ul>@Html.LabelFor(c => category.CategoryId)</ul>
        <ul>@Html.TextBoxFor(c => category.CategoryDescription, new { @class = "form-control" })</ul>
        @Html.HiddenFor(c => category.CategoryId)
        @Html.HiddenFor(c => category.CategoryDescription)

        foreach (var question in Model.Questions.Where(q => q.CategoryId == category.CategoryId))
        {
            <ul>@Html.LabelFor(q => question.QuestionId)</ul>
            <ul>@Html.TextBoxFor(q => question.QuestionText, new { @class = "form-control" })</ul>
            @Html.HiddenFor(q => question.QuestionId)
            @Html.HiddenFor(q => question.QuestionText)

            foreach (var answer in Model.Answers.Where(a => a.QuestionId == question.QuestionId))
            {
                <ul>@Html.LabelFor(a => answer.AnswerId)</ul>
                <ul>@Html.TextBoxFor(a => answer.AnswerText, new { @class = "form-control" })</ul>
                @Html.HiddenFor(a => answer.AnswerId)
                @Html.HiddenFor(a => answer.AnswerText)
            }
        }
    }
</div>
@Html.HiddenFor(m => m.SurveyId)
@Html.AntiForgeryToken()
<button type="submit" class="btn btn-primary">Save</button>
}

My guess is that somewhere in the view the data isn't being properly sent to the controller, otherwise it wouldn't be null. Does this problem originate from a bad send from the view to the controller?

The Class (view model) that is being used here is

public class NewSurveyViewModel
{
    public List<Category> Categories { get; set; }
    public List<Question> Questions { get; set; }
    public List<Answer> Answers { get; set; }
    [Display(Name = "Survey Name")]
    public int? SurveyId { get; set; }
    [Required(ErrorMessage = "The survey name cannot be blank")]
    public string Description { get; set; }

    public NewSurveyViewModel()
    {
        SurveyId = 0;
    }
}

I apologize for the huge block of code, but I figured this would all be relevant and didn't want to leave anything out for a better picture.

Nick
  • 61
  • 9
  • Why are you doing `Save(Survey survey, List category, List question, List answer)` instead of just `Save(NewSurveyViewModel viewModel)` – KSib Jan 20 '17 at 18:11
  • Please post the code that is calling the controller method, be it a redirect from another controller or just a post with form data from a view – ironstone13 Jan 20 '17 at 18:14
  • Isn't the save method being called from here? @using (Html.BeginForm("Save", "Surveys")) – Nick Jan 20 '17 at 18:16
  • Note in addition to the issue with using a `foreach` loop as described in the dupe, the POST method needs to be `public ActionResult Save(NewSurveyViewModel model)` - i.e the same model that you use in the view. But your view model is not correct to represent your view in any case and you should have a collection of Questions, which each Question containing a collection of Answers (but not sure where Category fits in) and you view should not contain linq queries –  Jan 20 '17 at 21:05
  • [This answer](http://stackoverflow.com/questions/28055287/asp-net-mvc-5-group-of-radio-buttons/28057533#28057533) might give you a better idea of what your view model and view needs to look like –  Jan 20 '17 at 21:12

0 Answers0