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