when collection is submitted back to controller ge

2019-05-29 00:53发布

问题:

I am updating multiple records and after I click submit button I get the error, which indicates that controller receives NULL and reports the following error at line 36 Below is the code for my controller, view and the model.

Object reference not set to an instance of an object. Description:

An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    Source Error: 

    Line 34:         public ActionResult UpdateAll(ICollection<Test0> test0s)
    Line 35:         {
    Line 36:             foreach (var tst in test0s)
    Line 37:             {
    Line 38:                 if (ModelState.IsValid)

    Source File: c:\users\rsc_vok\documents\visual studio 2010\Projects\MvcTest0\MvcTest0\Controllers\Test0Controller.cs    Line: 36

Here is the model:

namespace MvcTest0.Models
{
    public class Test0
    {
        public int id { get; set; }
        public int SectnID { get; set; }
        public string Section { get; set; }
        public string Comment { get; set; }
    }

    public class Test0DBContext : DbContext
    {
        public DbSet<Test0> Test0s { get; set; }
    }
}

And here is my controller code:

    public ActionResult UpdateAll(int id=0)
    {
        int sectnid = id;
        List<Test0> records = db.Test0s.ToList();
        var Sectnrecord = from r in records
                        where r.SectnID == sectnid
                        select r;

        return View(Sectnrecord.ToList());
    }

    [HttpPost]
    public ActionResult UpdateAll(ICollection<Test0> test0s)
    {
        foreach (var tst in test0s)
        {
            if (ModelState.IsValid)
            {
                db.Entry(tst).State = EntityState.Modified;
            }
        }
        db.SaveChanges();

        return View(test0s);
    }

And here is my view

      @model IEnumerable<MvcTest0.Models.Test0>

      @{
      ViewBag.Title = "UpdateAll";
     }

    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

   @using (Html.BeginForm())
   {
       @Html.ValidationSummary(true)

       var sectnHeader = new String[10];
       sectnHeader[0] = "A. QUALITY";
       sectnHeader[1] = "B. VR REFERRAL";
       var items = Model.ToArray();
       var sections = 1;
       for (var sectnLoop = 0; sectnLoop < sections; sectnLoop++)
       {
            <table>
                <tr>
                    <td>
                        <b>@(sectnHeader[sectnLoop])</b>
                    </td>
                </tr>  
            </table>
            <table>
                <tr>
                    <th>SectnID</th>
                    <th>Section</th>
                    <th>Comment</th>
                </tr>

            </table>
           for (var i = sectnLoop * 2; i < sectnLoop * 2 + 2; i++)
           {
               var sctnid = "sectnname" + i;
               @Html.HiddenFor(m => items[i].id)
               @Html.HiddenFor(m => items[i].SectnID)

               <table>
                  <tr>
                    <td>
                        @Html.DisplayFor(m => items[i].SectnID)
                    </td>
                    <td>
                        @Html.EditorFor(m => items[i].Section)
                        @Html.ValidationMessageFor(m => items[i].Section)
                    </td>
                    <td>
                        @Html.EditorFor(m => items[i].Comment)
                        @Html.ValidationMessageFor(m => items[i].Comment)
                    </td>
                 </tr>
                </table> 
           } 
       } 
        <p>
            <input type="submit" value="Save" />
        </p>
   }

回答1:

Solution:

  1. You have to change the view model to a collection type which support .Add() method:

    @model List<MvcTest0.Models.Test0>

  2. Change all the @Html.___For() helpers like:

    @Html.HiddenFor(m => m[i].id)
    @Html.HiddenFor(m => m[i].SectnID)
    @Html.DisplayFor(m => m[i].SectnID)
    @Html.EditorFor(m => m[i].Section)
    @Html.ValidationMessageFor(m => m[i].Section)
    @Html.EditorFor(m => m[i].Comment)
    @Html.ValidationMessageFor(m => m[i].Comment)
    

Notice that model has to be recreated in post back and IEnumerable has no method to add items to itself, unlike generic List.