2016-11-29 85 views
0

是否可以啓用模型綁定以及來自表單的發佈數據?在MVC 5中使用表單發佈混合模型?

我有,我想在foreach循環來遍歷每個選定的項目保存集合在集合屬性:

<div class="form-group"> 
     @Html.LabelFor(m => m.Users, new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @{ 
       List<ApplicationUser> allUsers = ViewBag.AllUsers; 
       bool assigned; 
      } 
      <div> 
       @foreach (var user in allUsers) 
       { 
//here I want to render all users, and only the users who are in the task, have a checked checkbox 

        assigned = Model.Users.Select(u => u.Id).Contains(user.Id); 
        <input type="checkbox" name="asndUsers" value="@user.Id" id="@user.Id" @Html.Raw(assigned ? "checked" : "") /> <label style="font-weight: normal;" for="@user.Id">@user.UserName</label><br /> 
       } 
      </div> 
     </div> 
    </div> 
//fields updated with model binding: 
    <div class="form-group"> 
     @Html.LabelFor(m => m.Status, new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(m => m.Status, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(m => m.Status) 
     </div> 
    </div> 

這是編輯動作後方法:

[HttpPost, ValidateAntiForgeryToken] 
public ActionResult Edit([Bind(Include = "Id,Title,Description,DueDate,Status")] UserTask task, string[] asndUsers) 
{ 
    if (ModelState.IsValid) 
    { 
     task.Users = new List<ApplicationUser>(); 
     foreach (var item in asndUsers) 
     { 
      var user = context.Users.Find(item); 
      task.Users.Add(user); 
     } 
     context.Entry(task).State = EntityState.Modified; 
     context.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(task); 
} 

它當我調試時,我看到新發布的數據已與綁定數據合併。 但是當重定向到索引視圖的要求,有編輯項後沒有變化,這是Index操作方法:

public ActionResult Index(int? taskId) 
{ 
    var viewModel = new TasksUsers(); 
    viewModel.Tasks = context.Tasks.Include(x => x.Users); 
    if (taskId != null) 
    { 
     viewModel.Users = viewModel.Tasks.Where(t => t.Id == taskId).Single().Users; 
     ViewBag.Row = taskId; 
    } 
    return View(viewModel); 
} 

回答

0

被調回任務由的DbContext不再跟蹤。嘗試Attach任務的DbSet在編輯動作:

context.Tasks.Attach(task); 
    if (task.Users == null) { 
     task.Users = new List<ApplicationUser>(); 
    } 
    foreach (var item in asndUsers) { 
     var user = context.Users.Find(item); 
     task.Users.Add(user); 
    } 
    // may be important because Attach() sets the State to 'Unchanged'? 
    context.Entry(task).State = EntityState.Modified; 
    context.SaveChanges(); 

作爲一個側面說明,你可以當你調用RedirectToAction傳遞參數。 (只有當你想編輯的任務的ID傳遞到Index操作做到這一點):

return RedirectToAction("Index", new { taskId = existingTask.Id }); 
//          ^^^^^^ 
//          must match parameter name of Index action 
+0

我在哪裏可以把這個代碼? – Mohamed

+0

將其放入POST編輯操作。我編輯了代碼以使用法更清晰。 –

+0

再次編輯,使用'Attach()',否則將失去通過模型綁定發送的其他值(即'Status')! –

1

原來的答覆

更新相關實體的正確方法是先加載它們, 所以就用預先加載重新定義傳入task參數作爲 如下:

task = context.Tasks.Include(t => t.Users).Single(s => s.Id == task.Id); Note that `Find` can't be used with `Include` so I used 

Single

這解決了更新用戶實體

這是錯誤的問題, 正確的方法是使用顯式綁定,而不是隱式綁定(TryUpdateModel()

+1

感謝分享! –

+0

歡迎您! – Mohamed

+0

我的回答錯了,對不起! – Mohamed