MVC Core 如何使用 viewmodel 正确编辑现有模型
MVC Core How to correctly Edit Existing model using viewmodel
我正在尝试使用视图模型编辑 class project
的现有实例。我认为我在 Edit 的 GET 方法中没有问题(视图上的一切都很好)但是我正在努力使用 POST 方法。问题是 POST 方法创建了 project
的新实例,而不是更新当前实例。
这是我的模型:
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
public Project()
{
}
}
}
这是我的CreateProjectViewModel(部分属性在下面的控制器代码中没有用到):
public class CreateProjectViewModel
{
//project
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
//clients
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
//Members
public int MemberId { get; set; }
public Member Member { get; set; }
public Project Project { get; set; }
public List<SelectListItem> Members { get; set; }
public IEnumerable<SelectListItem> Clients { get; set; }
public IEnumerable<int> SelectedMembers { get; set; }
public CreateProjectViewModel() { }
}
}
这是我在 ProjectController 中的编辑 GET 方法:
public async Task<IActionResult> Edit(int? id)
{
Project project = await _context.Project
.FirstOrDefaultAsync(m => m.ProjectId == id);
var members = _context.Member
.Select(m => new SelectListItem { Value = m.MemberId.ToString(), Text = m.MemberName }).ToList();
var clients = _context.Client
.Select(r => new SelectListItem { Value = r.ClientId.ToString(), Text = r.Name }).ToList();
CreateProjectViewModel viewmodel = new CreateProjectViewModel
{
Name = project.Name,
Budget = project.Budget,
BusinessCase = project.BusinessCase,
StartDate = project.StartDate,
FinishDate = project.FinishDate,
Project = project,
Clients = clients,
Members = members
};
return View(viewmodel);
这是我在 ProjectController 中的编辑 POST 方法,它错误地创建了一个新项目而不是更新当前项目:
(控制器正在尝试将值保存到项目模型,同时在包含 MemberId 和 ProjectID 的 Join table 中保存 - 这在创建项目时工作正常,不确定更新是否正确)
public IActionResult Edit(int? id, CreateProjectViewModel model)
{
Project project = _context.Project
.Single(m => m.ProjectId == id);
//this is to post in many-to-many join table between Member and Project
var projectID = project.ProjectId;
var memberID = model.MemberId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
foreach (var selectedId in model.SelectedMembers)
{
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
//this is to update the values in the project which refers to ProjectID
project.ProjectId = model.ProjectId;
project.Name = model.Name;
project.Budget = model.Budget;
project.BusinessCase = model.BusinessCase;
project.StartDate = model.StartDate;
project.FinishDate = model.FinishDate;
project.ClientId = model.ClientId;
_context.Entry(project).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
你们能告诉我在这两种方法中应该改变什么以获得预期的结果吗?
非常感谢。
经过一些挖掘后,这是工作代码。
编辑POST方法:
public IActionResult Edit(int? id, CreateProjectViewModel viewmodel)
{
if (ModelState.IsValid)
{
var project = _context.Project
.SingleOrDefault(m => m.ProjectId == id);
//this is to update the Project from the viewmodel
project.Name = viewmodel.Name;
project.Budget = viewmodel.Budget;
project.BusinessCase = viewmodel.BusinessCase;
project.StartDate = viewmodel.StartDate;
project.FinishDate = viewmodel.FinishDate;
project.ClientId = viewmodel.ClientId;
//code below is to validate if the matched primary keys of Project and Member are not already in ProjectMembers table
foreach (var selectedId in viewmodel.SelectedMembers)
{
var projectID = project.ProjectId;
var memberID = selectedId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
//this is to add new entry into ProjectMembers table
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
_context.SaveChanges();
}
return RedirectToAction("Index");
我正在尝试使用视图模型编辑 class project
的现有实例。我认为我在 Edit 的 GET 方法中没有问题(视图上的一切都很好)但是我正在努力使用 POST 方法。问题是 POST 方法创建了 project
的新实例,而不是更新当前实例。
这是我的模型:
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
public Project()
{
}
}
}
这是我的CreateProjectViewModel(部分属性在下面的控制器代码中没有用到):
public class CreateProjectViewModel
{
//project
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
//clients
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
//Members
public int MemberId { get; set; }
public Member Member { get; set; }
public Project Project { get; set; }
public List<SelectListItem> Members { get; set; }
public IEnumerable<SelectListItem> Clients { get; set; }
public IEnumerable<int> SelectedMembers { get; set; }
public CreateProjectViewModel() { }
}
}
这是我在 ProjectController 中的编辑 GET 方法:
public async Task<IActionResult> Edit(int? id)
{
Project project = await _context.Project
.FirstOrDefaultAsync(m => m.ProjectId == id);
var members = _context.Member
.Select(m => new SelectListItem { Value = m.MemberId.ToString(), Text = m.MemberName }).ToList();
var clients = _context.Client
.Select(r => new SelectListItem { Value = r.ClientId.ToString(), Text = r.Name }).ToList();
CreateProjectViewModel viewmodel = new CreateProjectViewModel
{
Name = project.Name,
Budget = project.Budget,
BusinessCase = project.BusinessCase,
StartDate = project.StartDate,
FinishDate = project.FinishDate,
Project = project,
Clients = clients,
Members = members
};
return View(viewmodel);
这是我在 ProjectController 中的编辑 POST 方法,它错误地创建了一个新项目而不是更新当前项目: (控制器正在尝试将值保存到项目模型,同时在包含 MemberId 和 ProjectID 的 Join table 中保存 - 这在创建项目时工作正常,不确定更新是否正确)
public IActionResult Edit(int? id, CreateProjectViewModel model)
{
Project project = _context.Project
.Single(m => m.ProjectId == id);
//this is to post in many-to-many join table between Member and Project
var projectID = project.ProjectId;
var memberID = model.MemberId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
foreach (var selectedId in model.SelectedMembers)
{
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
//this is to update the values in the project which refers to ProjectID
project.ProjectId = model.ProjectId;
project.Name = model.Name;
project.Budget = model.Budget;
project.BusinessCase = model.BusinessCase;
project.StartDate = model.StartDate;
project.FinishDate = model.FinishDate;
project.ClientId = model.ClientId;
_context.Entry(project).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
你们能告诉我在这两种方法中应该改变什么以获得预期的结果吗?
非常感谢。
经过一些挖掘后,这是工作代码。
编辑POST方法:
public IActionResult Edit(int? id, CreateProjectViewModel viewmodel)
{
if (ModelState.IsValid)
{
var project = _context.Project
.SingleOrDefault(m => m.ProjectId == id);
//this is to update the Project from the viewmodel
project.Name = viewmodel.Name;
project.Budget = viewmodel.Budget;
project.BusinessCase = viewmodel.BusinessCase;
project.StartDate = viewmodel.StartDate;
project.FinishDate = viewmodel.FinishDate;
project.ClientId = viewmodel.ClientId;
//code below is to validate if the matched primary keys of Project and Member are not already in ProjectMembers table
foreach (var selectedId in viewmodel.SelectedMembers)
{
var projectID = project.ProjectId;
var memberID = selectedId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
//this is to add new entry into ProjectMembers table
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
_context.SaveChanges();
}
return RedirectToAction("Index");