MVC strongly typed view returns a null model on post back


I recently ran into a problem where a form I had built (using the view creation dialogue) would always return a null model on post back.  The code was pretty simple;

        //
        // GET: /StockAdjustment/CreateForPart/{PartId}
        //[RequireRequestValue("id")]
        [Authorize(Roles = "Administrator")]
        public ActionResult CreateForPart(Guid id)
        {
            StockAdjustment sa = new StockAdjustment() {
                Part = parts_repo.GetPart(id)
            };

            return View(sa);
        }

        //
        // POST: /StockAdjustment/CreateForPart/{PartId}
        [Authorize(Roles = "Administrator")]
        [HttpPost]
        public ActionResult CreateForPart(Guid id, StockAdjustment adjustment)
        {
            if (ModelState.IsValid)
            {
                adjustment.AddedBy = User.Identity.Name;
                adj_repo.Add(adjustment);
                adj_repo.Save();

                return RedirectToAction("Details", "Parts", new { Id = id });
            }
            else
            {
                adjustment.Part = parts_repo.GetPart(id);
                return View(adjustment);
            }
        }

The ModelState would always be invalid, despite the the fact that my data was all valid and fine. When I picked into the ModelState error using immediate mode I found the reported error;

ModelState.ToList()[0]
  {[id, System.Web.Mvc.ModelState]}
ModelState.ToList()[0].Value.Errors
  Count = 0
ModelState.ToList()[1].Value.Errors
Count = 1
    [0]: {System.Web.Mvc.ModelError}
ModelState.ToList()[1]
  {[adjustment, System.Web.Mvc.ModelState]}
ModelState.ToList()[1].Value.Errors[0]
{System.Web.Mvc.ModelError}
    ErrorMessage: ""
    Exception: {"The parameter conversion from type 'System.String' to type 
    'SimplyModel.Models.StockAdjustment' failed because no type converter can convert between these types."}

So model state contained the ID which had no errors, and adjustment which has this weird type conversion error. After a bit of hunting around my code I realised the problem- StockAdjustment has a field called adjustment which is an integer, however on my post back handler, i told MVC that my model instance should be called adjustment- so it looks like the MVC binder has got confused and figured the form field “adjustment” must represent the entire StockAdjustment model- i simply changed the method signature to accept the model with another name, and it all started to work;

        //
        // POST: /StockAdjustment/CreateForPart/{PartId}
        [Authorize(Roles = "Administrator")]
        [HttpPost]
        public ActionResult CreateForPart(Guid id, StockAdjustment a)
        {
            if (ModelState.IsValid)
            {
                a.AddedBy = User.Identity.Name;
                adj_repo.Add(a);
                adj_repo.Save();

                return RedirectToAction("Details", "Parts", new { Id = id });
            }
            else
            {
                a.Part = parts_repo.GetPart(id);
                return View(a);
            }
        }
  1. #1 by Stanislaus on January 23, 2011 - 20:11

    Thank you, thank you, thank you!

    [Note to self: next time, Google FIRST, before throwing away half an hour...]

  2. #2 by shawson on January 31, 2011 - 10:13

    :) glad I was able to help!

  3. #3 by resul on April 12, 2011 - 14:58

    thank you. it helped me a lot :)

  4. #4 by Sergio Migueis on August 4, 2011 - 22:44

    Dude, thanks, from Brasil, thanks a lot, Books, hours of researching and i almost did like Stanislaus up there…. thanks lord i found ur site

  5. #5 by Andy Olivares on October 19, 2011 - 05:23

    Hey dude! Many thanks! It saved me a lot of time :)

  6. #6 by kevin b on January 21, 2012 - 20:31

    Was having trouble with a login form on my site because my variable name was model. Thank you for your help, saved me time :) . That will be a good one to remember.

  7. #7 by Dinesh on June 1, 2012 - 06:48

    Fantastic.. Same issue wasted few of my hours !!. Many thanks

  8. #8 by David on September 6, 2012 - 22:01

    Just fixed my problem!

    In short, I tried to submit a form (for a new Car) with a field called ‘Model’. This error came up because the Controller Action has a parameter on the POST called ‘model’.

  9. #9 by Joe on January 1, 2013 - 22:36

    Thanks mate. Sometimes MVC “Magic” is quite evil!

(will not be published)