Pregunta

When I Edit my model, all properties are saved correctly except for a nullable property which always loses its value in the process.

I have tried to hide the property in my view as such:

@Html.HiddenFor(model => model.UserId)

In my controller's Edit method I tried to:

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(ItemViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                var item= db.Items.Find(viewModel.ItemId);
                Mapper.Map<ItemViewModel, Item>(viewModel, item);
                //db.Entry(item).State = EntityState.Modified;
                if (TryUpdateModel(item))
                {
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
            }
            ViewBag.UserId = new SelectList(db.Users, "UserId", "Username", viewModel.UserId);
            return View(viewModel);
        }

I also tried without the TryUpdateModel and with the UpdateModel(model) method. I even tried reassign it the property value from the ViewModel to the Model manually just before saving the changes.

When I put breakpoints throughout the method I can see that the property still holds its value but as soon as I hit Save it becomes null.

Note that if I uncomment the EntityState.Modified line I am no longer losing the property value but I am handling this stuff in my DbContext (I have different type of edit events for different property and having this line of code uncommented in my controller seems to triger all of my edit events even if nothing changed).

Please note that this property is also a Foreign key (not sure if it actually matters here)

¿Fue útil?

Solución

TryUpdateModel doesn't actually do anything to the item passed into it. It merely runs model validation on it. Whatever values were there, remain there.

I think I know what the issue is, and it's related to AutoMapper. Your posted model most likely doesn't include the actual related user object, just the id you posted for that. When you map your model onto your entity, AutoMapper is replacing the value for the related user object with null, since the model doesn't have it. Try adding the following to your CreateMap:

.ForMember(dest => dest.User, opts => opts.Ignore());

Otros consejos

What I am saying is all of your code is correct except for this line:

 Mapper.Map<ItemViewModel, Item>(viewModel, item);

That line should be

 item = Mapper.Map<ItemViewModel, Item>(viewModel, item);

Then at some point you need to pass that to the repository:

 db.Update(item);
 db.SaveChanges();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top