在这个演示应用程序中,我想让用户能够通过下拉列表将TODO分配给其他用户。使用ApplicationUsers填充下拉列表,但是当用户选择新的ApplicationUser时,User值为null。
除用户外,记录的所有值都会更新。我怎么能克服这个?
相关代码部分如下所示。谢谢你的帮助!
ToDo模型:
namespace DELTODOS.Models
{
public class ToDo
{
public int Id { get; set; }
public string Description { get; set; }
public bool IsDone { get; set; }
public virtual ApplicationUser User { get; set; }
}
}
更新了ApplicationUser类:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public virtual ICollection<ToDo> todos { get; set; }
}
修改视图:
@model DELTODOS.Models.ToDo
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>ToDo</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.User, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.User.Id, new SelectList((ViewBag.UserId) as SelectList, "Value", "Text"), "Select", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.User.Id, "", new { @class = "text-danger"})
</div>
</div>
ToDosController编辑操作:
namespace DELTODOS.Controllers
{
public class ToDosController : Controller
{
private UserManager<ApplicationUser> manager;
private ApplicationDbContext db = new ApplicationDbContext();
public ToDosController()
{
db = new ApplicationDbContext();
manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
}
// GET: ToDos/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
//return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
return RedirectToAction("Index");
}
ToDo toDo = await db.ToDoes.FindAsync(id);
if (toDo == null)
{
return HttpNotFound();
}
ViewBag.UserId = new SelectList(db.Users, "Id", "Email", toDo.User.Id);
return View(toDo);
}
// POST: ToDos/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,Description,IsDone,UserId")] ToDo toDo)
{
if (ModelState.IsValid)
{
//var selectedUser = await manager.FindByIdAsync("whatever");
//toDo.User = selectedUser;
db.Entry(toDo).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(toDo);
}
}
}
答案 0 :(得分:0)
你无法通过这种方式处理它。当尝试通过id关联相关项时,您需要在模型上使用外键的实际属性或使用该ID从数据库中查找实例,然后手动设置它。 / p>
在第一种情况下,您可以添加如下属性:
public string UserId { get; set; }
public ApplicationUser User { get; set; }
然后,使用下拉列表发布到此UserId
媒体资源:
@Html.DropDownListFor(m => m.UserId, ...)
在第二种情况下(您目前拥有的代码),您仍然需要UserId
或类似的属性才能发布,但这可能是在视图模型而不是您的实际实体类。例如:
public class ToDoViewModel
{
public int Id { get; set; }
public string Description { get; set; }
public bool IsDone { get; set; }
public string UserId { get; set; }
}
然后,在你的帖子中:
[HttpPost]
public ActionResult Edit(int id, ToDoViewModel model)
{
var todo = db.ToDos.Find(id);
if (todo == null)
{
return new HttpNotFoundResult();
}
if (ModelState.IsValid)
{
// Map posted data to existing entity
todo.Description = model.Description;
todo.IsDone = model.IsDone;
// setting user to one pulled from database
todo.User = db.Users.Find(model.UserId);
db.Entry(todo).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}