Combined Multiple Models into Single View - Create Problem
-
I'm trying to combine the Address and Country Create Views into a single view. I'm using MVC 3 with Repository Scaffolding & ASPX Views. I currently have a Country drop-down list that is already populated, and am trying to add this to the Address Create View. I have the Edit View working just fine. However when I try to create a new Address it adds a new Country with a blank name even though I choose a Country in the drop down list. I feel like I'm missing something very fundamental because this should be easy. POCO Classes public class Address { public int ID { get; set; } public string Street1 { get; set; } public string Street2 { get; set; } public string City { get; set; } public string State { get; set; } public string PostalCode { get; set; } [ForeignKey("Country")] public int CountryID { get; set; } public Country Country { get; set; } } public class Country { public int ID { get; set; } [Display(Name = "Country"), MaxLength(50)] public string Name { get; set; } } Address Controller public class AddressController : Controller { private readonly IAddressRepository addressRepository; private readonly ICountryRepository countryRepository; // If you are using Dependency Injection, you can delete the following constructor public AddressController() : this(new AddressRepository(), new CountryRepository()) { } public AddressController(IAddressRepository addressRepository, ICountryRepository countryRepository) { this.addressRepository = addressRepository; this.countryRepository = countryRepository; } // // GET: /Address/ public ViewResult Index() { return View(addressRepository.All); } // // GET: /Address/Details/5 public ViewResult Details(int id) { return View(addressRepository.Find(id)); } // // GET: /Address/Create public ActionResult Create() { ViewBag.PossibleCountries = countryRepository.All; return View(); } // // POST: /Address/Create [HttpPost] public ActionResult Create(Address address) { if (ModelState.IsValid) { addressRepository.InsertOrUpdate(address); addressRepository.Save(); return RedirectToAction("Index"); } else { ViewBag.PossibleCountries = countryRepository.All; return View(); } } // // GET: /Address/Edit/5 public ActionResult Edit(int id) { ViewBag.PossibleCountries = countryRepository.All; return View(addressRepository.Find(id)); } // // POST: /Address/Edit/5 [HttpPost] public ActionResult Edit(Address address) { if (ModelState.IsValid) { addressRepository.InsertOrUpdate(address); addressRepository.Save(); return RedirectToAction("Index"); } else { ViewBag.PossibleCountries = countryRepository.All; return View(); } } // // GET: /Address/Delete/5 public ActionResult Delete(int id) { return View(addressRepository.Find(id)); } // // POST: /Address/Delete/5 [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { addressRepository.Delete(id); addressRepository.Save(); return RedirectToAction("Index"); } } Country Controller public class CountryController : Controller { private readonly ICountryRepository countryRepository; // If you are using Dependency Injection, you can delete the following constructor public CountryController() : this(new CountryRepository()) { } public CountryController(ICountryRepository countryRepository) { this.countryRepository = countryRepository; } // // GET: /Country/ public ViewResult Index() { return View(countryRepository.All); } // // GET: /Country/Details/5 public ViewResult Details(int id) { return View(countryRepository.Find(id)); } // // GET: /Country/Create public ActionResult Create() { return View(); } // // POST: /Country/Create [HttpPost] public ActionResult Create(Country country) { if (ModelState.IsValid) { countryRepository.InsertOrUpdate(country); countryRepository.Save(); return RedirectToAction("Index"); } else { return View(); } } // // GET: /Country/Edit/5 public ActionResult Edit(int id) { return View(countryRepository.Find(id)); } // // POST: /Country/Edit/5 [HttpPost] public ActionResult Edit(Country country) { if (ModelState.IsValid) { countryRepository.InsertOrUpdate(country); countryRepository.Save(); return RedirectToAction("Index"); } else { return View(); } } // // GET: /Country/Delete/5 public ActionResult Delete(int id) { return View(countryRepository.Find(id)); } // // POST: /Country/Delete/5 [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { countryRepository.Delete(id); countryRepository.Save(); return RedirectToAction("Index"); } } Address Repository public class AddressRepository : IAddressRepository { AddressTestContext context = new AddressTestContext(); public IQueryable<Address> All { get { return context.Addresses; } } public IQueryable<Address> AllIncluding(params Expression<Func<Address, object>>[] includeProperties) { IQueryable<Address> query = context.Addresses; foreach (var includeProperty in includeProperties) { query = query.Include(includeProperty); } return query; } public Address Find(int id) { return context.Addresses.Find(id); } public void InsertOrUpdate(Address address) { if (address.ID == default(int)) { // New entity context.Addresses.Add(address); } else { // Existing entity address.CountryID = address.Country.ID; context.Entry(address).State = EntityState.Modified; } } public void Delete(int id) { var address = context.Addresses.Find(id); context.Addresses.Remove(address); } public void Save() { context.SaveChanges(); } } public interface IAddressRepository { IQueryable<Address> All { get; } IQueryable<Address> AllIncluding(params Expression<Func<Address, object>>[] includeProperties); Address Find(int id); void InsertOrUpdate(Address address); void Delete(int id); void Save(); } Address CreateOrEdit.ascx View <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<AddressTest.Models.Address>" %> <div class="editor-label"> <%: Html.LabelFor(model => model.Street1) %> </div> <div class="editor-field"> <%: Html.EditorFor(model => model.Street1) %> <%: Html.ValidationMessageFor(model => model.Street1) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Street2) %> </div> <div class="editor-field"> <%: Html.EditorFor(model => model.Street2) %> <%: Html.ValidationMessageFor(model => model.Street2) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.City) %> </div> <div class="editor-field"> <%: Html.EditorFor(model => model.City) %> <%: Html.ValidationMessageFor(model => model.City) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.State) %> </div> <div class="editor-field"> <%: Html.EditorFor(model => model.State) %> <%: Html.ValidationMessageFor(model => model.State) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.PostalCode) %> </div> <div class="editor-field"> <%: Html.EditorFor(model => model.PostalCode) %> <%: Html.ValidationMessageFor(model => model.PostalCode) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Country) %> </div> <div class="editor-field"> <%: Html.DropDownListFor(model => model.Country.ID, ((IEnumerable<AddressTest.Models.Country>)ViewBag.PossibleCountries).Select(option => new SelectListItem { Text = (option == null ? "None" : option.Name), Value = option.ID.ToString(), Selected = (Model != null) && (option.ID == Model.CountryID) }), "Choose...") %> <%: Html.ValidationMessageFor(model => model.Country.ID) %> </div>
-
Answer:
Create the drop down list for the scalar property CountryID instead of Country.ID <div class="editor-field"> <%: Html.DropDownListFor(model => model.CountryID, new SelectList((IEnumerable<AddressTest.Models.Country>)ViewBag.PossibleCountries, "ID", "Name"), "Choose...") %> <%: Html.ValidationMessageFor(model => model.CountryID) %> </div> I would modify the Address POCO to make CountryID nullable and apply Required attribute public class Address { public int ID { get; set; } public string Street1 { get; set; } public string Street2 { get; set; } public string City { get; set; } public string State { get; set; } public string PostalCode { get; set; } [ForeignKey("Country")] [Required] public int? CountryID { get; set; } public Country Country { get; set; } }
Sephrial at Stack Overflow Visit the source
Related Q & A:
- How to pass multiple parameters in a single Ajax function?Best solution by stackoverflow.com
- How to merge multiple CSV files into a single CSV file?Best solution by solveyourtech.com
- How to tag multiple friends into single image?Best solution by facebook.com
- How can display multiple values to single column?Best solution by Stack Overflow
- Multiple signing in on Messenger problem?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.