我正在使用带有个人用户帐户的实体框架和MVC,我有一个名为"Kit"的表,该表具有链接到AspNetUser 'ID'作为外键的UserId列。
当我创建一个新工具包并保存到数据库时,我希望工具包表的"UserId"是当前登录的ASPNet用户。
但是目前,当我创建新的Kit对象时,它只是将UserId设置为NULL,并且永远不会选择当前登录的用户。
我在这里错过了什么?
控制器创建()
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public ActionResult Create([Bind(Include = "KitId,KitName,ProductId,UserId")] Kit kit)
{
if (ModelState.IsValid)
{
db.Kits.Add(kit);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ProductId = new SelectList(db.Products, "ProductId", "ProductName", kit.ProductId);
ViewBag.UserId = new SelectList(db.AspNetUsers, "Id", "Email", kit.UserId);
return View(kit);
}
视图
<div class="form-group">
@Html.LabelFor(model => model.AspNetUser.Id, "User", htmlAttributes: new { @class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.UserId, "Email", new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } })
</div>
</div>
这是我数据库中的行,您可以看到从未填充过UserId
KitId KitName ProductId Available LoanId UserId
3 TestKit 12 NULL NULL NULL
禁用的控件不提交值,因此 POST 方法中的UserId
值将被null
(属性的默认值 - 尽管不清楚为什么将其设置为可为空)。虽然您可以将输入设为只读(使用new { @readonly = "readonly" }
),但正确的方法是在保存记录之前立即在 POST 方法中设置属性的值,以防止恶意用户回发无效数据并发现其他用户的 ID。
if (ModelState.IsValid)
{
kit.UserId = User.Identity.GetUserId(); // assumes your using Identity
db.Kits.Add(kit);
...
至少,[Bind]
属性应排除KitId
和UserId
属性,但是首选方法(尤其是在编辑数据时)是使用仅包含视图中所需属性的视图模型,并且该视图模型还将包含下拉列表中IEnumerable<SelectListItem>
属性,而不是使用ViewBag
。请参阅什么是 MVC 中的视图模型?。
作为旁注,将SelectList
命名为与绑定到的属性相同,该属性将无法正常工作(有关详细说明,请参阅 ViewBag 名称是否与 DropDownList 中的模型属性名称相同?),并且使用SelectList
构造函数的第 4 个参数设置Selected
属性是没有意义的(绑定到模型属性时忽略它)