如何参考不同的ApplicationUser更新数据库记录?

时间:2014-12-03 16:48:43

标签: asp.net-mvc entity-framework

在这个演示应用程序中,我想让用户能够通过下拉列表将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);
        }
    }
}

1 个答案:

答案 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);
}