我正在尝试将地址和国家/地区创建视图合并到一个视图中。我正在使用MVC 3和Repository Scaffolding& ASPX视图。我目前有一个已填充的国家/地区下拉列表,我正在尝试将其添加到地址创建视图中。我有编辑视图工作得很好。但是,当我尝试创建一个新地址时,即使我在下拉列表中选择了一个国家/地区,它也会添加一个空白名称的新国家/地区。我觉得我错过了一些非常基础的东西,因为这应该很容易。
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; }
}
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");
}
}
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");
}
}
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();
}
<%@ 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>
答案 0 :(得分:1)
为标量属性CountryID
创建下拉列表,而不是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>
我会修改Address
POCO以使CountryID
可以为空并应用Required
属性
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; }
}