Search code examples
asp.netasp.net-mvc-2data-annotations

TryUpdateModel not updating object after property value has changed


I'm using MVC 2 and EF4. I have a view that displays my Application (class) properties. Not all the properties are displayed in the view. There are a couple of the properties that need to be set once the submit button is clicked.

I'm getting client validation to pass, but my server validation is still failing. I receive an Application object in my CreateApplication action, I update a property, and do a ModelState.IsValid check. It is still false. I did a loop through my errors list and it displays the error text that I set on my SubmitterEmployeeNumber property using a Required data annotation. I did set it and I did update my model, but validation is still failing. Here is my code:

[HttpPost]
public ActionResult CreateApplication(Application application)
{
   application.SubmitterEmployeeNumber = "123456";

   TryUpdateModel(application);

   if (ModelState.IsValid)
   {
   }
}

Here is how I display the view:

public ActionResult CreateApplication()
{
   var viewModel = new ApplicationViewModel(new Application(), db.AccountTypes);

   return View(viewModel);
}

How do I get the validation to pass after I set the property after binding?

What is the difference between UpdateModel and TryUpdateModel and when do I need to use each?

EDIT:

I changed the name of the action to:

[HttpPost]
public ActionResult CreateApp()
{
   var application = new Application
   {
      ApplicationStateID = 1,
      SubmitterEmployeeNumber = "123456"
   };

   if (TryUpdateModel(application))
   {
      int success = 0;
   }
}

Here is my view:

<% using (Html.BeginForm("CreateApp", "Application")) {%>

TryUpdateModel still validates as false. I put in int success = 0; just to see if it will go into it but it doesn't.


Solution

  • [HttpPost]
    public ActionResult CreateApplication()
    {
        var application = new Application 
        {
            SubmitterEmployeeNumber = "123456"
        };
        if (TryUpdateModel(application)) 
        {
            // The model is valid => submit values to the database
            return RedirectToAction("Success");
        }
        return View(application);
    }
    

    UPDATE: Due to many confusions in the comments section here's a full working example.

    Model:

    public class Application
    {
        [Required]
        public int? ApplicationStateID { get; set; }
    
        [Required]
        public string SubmitterEmployeeNumber { get; set; }
    
        [Required]
        public string Foo { get; set; }
    
        [Required]
        public string Bar { get; set; }
    }
    

    Controller:

    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var application = new Application();
            return View(application);
        }
    
        [HttpPost]
        [ActionName("Index")]
        public ActionResult Create()
        {
            var application = new Application
            {
                ApplicationStateID = 1,
                SubmitterEmployeeNumber = "123456"
            };
            if (TryUpdateModel(application))
            {
                // success => update database, etc...
                return Content("yupee");
            }
    
            // failure => redisplay view to fix errors
            return View(application);
        }
    }
    

    View:

    <% using (Html.BeginForm()) { %>
        <div>
            <%: Html.LabelFor(x => x.Foo) %>
            <%: Html.TextBoxFor(x => x.Foo) %>
            <%: Html.ValidationMessageFor(x => x.Foo) %>
        </div>
    
        <div>
            <%: Html.LabelFor(x => x.Bar) %>
            <%: Html.TextBoxFor(x => x.Bar) %>
            <%: Html.ValidationMessageFor(x => x.Bar) %>
        </div>
    
        <input type="submit" value="GO GO" />
    <% } %>
    

    Hope this clears things up.