2014-12-03 56 views
0

在這個演示程序中,我想讓用戶能夠通過下拉列表爲其他用戶分配TODO。下拉列表由ApplicationUser填充,但是當用戶選擇新的ApplicationUser時,User值爲空。如何參考不同的ApplicationUser更新數據庫記錄?

記錄的所有值都會更新,用戶除外。我該如何克服這一點?

相關代碼部分如下所示。謝謝你的幫助!

待辦事項型號:

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

你不能這樣處理它。嘗試通過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); 
}