我正在尝试使用MVC6和Entity Framework 7将我的下拉列表值保存到ASP.NET Web应用程序中的数据库,但值不保存。
我有两个名为费用的课程,当用户创建费用时,他们需要选择一个国家/地区。我填写了国家/地区下拉列表,但是当保存费用时,countryid没有保存到数据库中。
模型
public class Country
{ public int Countryid { get; set; }
public string CountryCode { get; set; }
}
public class Expense
{
public int ExpenseId { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",
ApplyFormatInEditMode = true)]
public DateTime ExpenseDate { get; set; }
public virtual Country Countryid { get; set; }
费用控制器
private void PopulateCountriesDropDownList(object selectedCountry = null)
{
var list = _context.Countries.OrderBy(r => r.CountryCode).ToList().Select(rr =>
new SelectListItem { Value = rr.Countryid.ToString(), Text = rr.CountryCode }).ToList();
ViewBag.Countries = list;
}
// GET: Expenses/Create
public IActionResult Create()
{
PopulateCountriesDropDownList();
return View();
}
// POST: Expenses/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Expense expense)
{
if (ModelState.IsValid)
{
_context.Expenses.Add(expense);
_context.SaveChanges();
return RedirectToAction("Index");
}
PopulateCountriesDropDownList(expense.Countryid);
return View(expense);
}
查看
<div class="form-group">
<label asp-for="Countryid" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="Countryid" class="form-control"asp-items=@ViewBag.Countries></select>
<span asp-validation-for="Countryid" class="text-danger" />
</div>
</div>
答案 0 :(得分:1)
首先,Expense模型中的Countryid
属性是一个复杂类型(Country
)。模型绑定器无法将发布的Countryid
表单值映射到此Complex对象。
您应该将CountryId属性添加到Int
类型的Expense模型中public class Expense
{
public int ExpenseId { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",
ApplyFormatInEditMode = true)]
public DateTime ExpenseDate { get; set; }
public int CountryId { set;get;}
public virtual Country Country { get; set; }
}
虽然这样可以解决问题,但更好一点。干净的解决方案是使用视图模型在视图和操作方法之间传输数据。使用此方法,您的视图不会与ORM生成的实体类紧密耦合。
因此,为 视图创建一个视图模型,其中包含视图所需的属性 。
public class CreateExpenseVm
{
public List<SelectListItem> Countries { set;get;}
public int CountryId { set;get;}
//Add other properties, if your view need them.
}
在您的GET操作中,您创建此类的对象,加载Countries集合属性并将其发送到您的视图。
public ActionResult Create()
{
var vm=new CreateExpenseVm();
vm.Countries = _context.Countries.OrderBy(r => r.CountryCode)
.Select(x=>new SelectListItem { Value=x.CountryId.ToString(),
Text=x.CountryCode}).ToList();
return View(vm);
}
在您看来,这是我们的新视图模型的强类型,
@model CreateExpenseVm
<form asp-controller="Expense" asp-action="Create">
<label>Select Country</label>
<select asp-for="CountryId" asp-items="@Model.Countries" >
<option>Please select one</option>
</select>
<input type="submit"/>
</form>
并在您的HttpPost操作中,使用CreateExpenseVm
作为参数类型。提交表单时,默认模型绑定器将能够将发布的表单数据映射到此类对象的属性。
[HttpPost]
public ActionResult Create(CreateExpenseVm model)
{
var e=new Expense { CountryId=model.CountryId };
e.ExpenseDate = DateTime.Now;
dbContext.Expenses.Add(e);
dbContext.SaveChanges();
return RedirectToAction("Index");
}