0

I am displaying a list of items in a Collection in edit mode in a view. after editing the documents, I want to submit. But I am unable to postback the list. List shows null.

here is my View

@model List<NewsLetter.Models.NewsLetterQuestions>



@using (Html.BeginForm("GetAnswersfromUser", "NewsLetter", FormMethod.Post, null))
{
    @Html.AntiForgeryToken()

foreach (var item in Model) {


        <div>
            @Html.DisplayFor(modelItem => item.Question)
        </div>

        <div>
            @Html.TextAreaFor(modelItem => item.Answer)
        </div>

}
       <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Submit" class="btn btn-default" />
            </div>
        </div>

}

Here is my Controller

 public ActionResult GetAnswersfromUser(string id)
        {
            id = "56c5afc9afb23c2df08dd2bf";
            List<NewsLetterQuestions> questions = new List<NewsLetterQuestions>();
            var ques = context.NewsLetterQuestionCollection.Find(Query.EQ("NewsLetterId", id));
            foreach(var x in ques)
            {
            questions.Add(x);
            }

            return PartialView(questions);
        }

        [HttpPost]
        public ActionResult GetAnswersfromUser(List<NewsLetterQuestions> nql)
        {

            string id = "56c5afc9afb23c2df08dd2bf";
            foreach (var item in nql)
            {
                var query = Query.And(Query.EQ("NewsLetterId", id), Query.EQ("Question", item.Question));
            var update=Update<NewsLetterQuestions>
                                     .Set(r => r.Answer, item.Answer);
            context.NewsLetterQuestionCollection.Update(query,update);

            }
            return RedirectToAction("NewsLetterIndex");

        }

When i hit submit it throws error.

System.NullReferenceException: Object reference not set to an instance of an object. In the line foreach (var item in nql)

which means that nql is null.

Shahzad Ahamad
  • 809
  • 1
  • 11
  • 30

2 Answers2

3

In order for the model binder to be able to bind the posted data, all your input names need to be in the format of [N].Property, where N is the index of the item within the list. In order for Razor to generate the input names properly, then, you need to pass it an indexed item, which means you need a for loop, rather than a foreach:

@for (var i = 0; i < Model.Count(); i++)
{
    ...

    @Html.TextAreaFor(m => m[i].Answer)

    ...
}
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
-1

You're never passing the list back to the controller's Post handler. You need to route the list back to the controller.

You should be doing something similar to this untested code :)

Html.BeginForm("Index", "Home", new { @nql=Model }, FormMethod.Post)

Take a look at this post as well. It is similar to your issue: Pass multiple parameters in Html.BeginForm MVC4 controller action and this Pass multiple parameters in Html.BeginForm MVC

Community
  • 1
  • 1
Mikanikal
  • 1,082
  • 8
  • 12
  • It is not throwing error now but nql still does not contain any value – Shahzad Ahamad Feb 18 '16 at 14:00
  • Oh for the love of all things good and holy, no, don't pass the whole model as a frickin' query string param. Besides, this doesn't even work since the post will override the query string. – Chris Pratt Feb 18 '16 at 14:22
  • @ChrisPratt I was simply giving him the concept of passing the items he required back to the controller. Something he obviously missed. Rather than write out the exact code for him, I provided links to previously answered questions that would fit his needs. – Mikanikal Feb 18 '16 at 15:09
  • There's no situation where the code sample you provided is remotely acceptable. Not only bad form (and potentially dangerous) to pass an entire model via a query string, the passed values would be the values at the time of page load, unaffected by anything the user submitted. And again, even then, the post itself overrides the query string. It's just 100% wrong. Period. – Chris Pratt Feb 18 '16 at 15:12