I have a Company model that has a one-to-one relationship with an Address model. I am using a view model for my create, detail, edit, and update actions. I am using AutoMapper to map from model to view model and vice versa.
My view model used to contain a property exposing the Company's Address:
public Address Address { get; set; }
I recently changed this to abstract the Address data and achieve validation on some properties of the address (See my related question here for more info...)
After those changes, I had properties like:
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
// etc...
This broke my AutoMapper. Based on the answer to my other question, I decided to use the flattening feature of AutoMapper. I changed my property names to match the naming convention of Navigation_propertyProperty:
public string AddressAddress1 { get; set; }
public string AddressAddress2 { get; set; }
public string AddressCity { get; set; }
// etc...
I modified my views to use these new property names, and it worked! Well, sort of. If I view the details of a company, I can see its address. If I delete a company, the address is successfully deleted as well. However, on an edit, company properties I change are saved but address properties are not. If I create a new company, it is created without an address.
So it seems the AutoMapper is working (it is able to pull the address for existing companies) but updates are not making it into the database... If I manually map the view model properties to the company.Address properties it works, but I can't figure out how to get this to work with AutoMapper.
Do I need to change the way I am saving the data in the controller, by telling the context to specifically update the address or something?
Here's my controller's Edit methods for reference:
public ActionResult Edit(int id = 0)
{
Company company = db.Companies
.Include(c => c.Address)
.Where(c => c.CompanyID == id)
.Single();
// Make sure we found something
if (company == null)
return HttpNotFound();
// Use AutoMapper to map model to viewmodel
CompanyViewModel viewModel = Mapper.Map<Company, CompanyViewModel>(company);
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CompanyViewModel viewModel)
{
if (ModelState.IsValid)
{
// Find appropriate record in DB
Company company = db.Companies
.Include(c => c.Address)
.Where(c => c.CompanyID == viewModel.CompanyID)
.Single();
// Map viewmodel data to company object
Mapper.Map<CompanyViewModel, Company>(viewModel, company);
// I've also tried the following without success:
// Mapper.Map(viewModel, company);
// company = Mapper.Map<CompanyViewModel, Company>(viewModel, company);
// Save and redirect to company list
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel);
}
Any help is appreciated. As mentioned, I can always manually map from the view model to the object to update/create (indeed, some would argue that's a better practice for writing to the DB in general) but I am curious as to why the mapping works in one direction only...Please let me know if you need more code...