【问题标题】:How to update database record with reference to a different ApplicationUser?如何参考不同的 ApplicationUser 更新数据库记录?
【发布时间】:2021-02-08 18:58:36
【问题描述】:

在这个演示应用程序中,我想让用户能够通过下拉列表将 TODO 分配给其他用户。下拉列表中填充了 ApplicationUser,但当用户选择新的 ApplicationUser 时,User 值为 null。

记录的所有值都会更新,除了用户。我该如何克服呢?

相关代码部分如下所示。

待办事项模型:

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

【问题讨论】:

    标签: asp.net-mvc entity-framework


    【解决方案1】:

    你不能这样处理。当尝试通过 id 关联相关项目时,您需要模型上的外键的实际属性使用 id 从数据库中查找实例,然后手动设置。

    在第一种情况下,您可以添加如下属性:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多