gpt4 book ai didi

c# - MVC Controller 未绑定(bind) ViewModel

转载 作者:行者123 更新时间:2023-11-30 16:22:22 25 4
gpt4 key购买 nike

我希望你能帮助我,我对 MVC 和 Entity Framework 还很陌生,并试图了解它。我正在使用 MVC4 和 EF5。

这是我正在尝试做的事情的概述...

我有两个实体,Site 和 SiteType。每个站点都可以有多个站点类型,因此它们具有多对多关系。我通过创建 3 个表 Site、SiteType 和 SiteSiteType 来设置具有典型多对多关系的数据库。 SiteSiteType 仅包含 2 列,SiteId 和 SiteType Id。

我更新了实体模型,它完美地为站点创建了我这样的实体...

public partial class Site
{
public Site()
{
this.SiteTypes = new HashSet<SiteType>();
}

public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }

public virtual ICollection<SiteType> SiteTypes { get; set; }
}

这是针对 SiteType 的

public partial class SiteType
{
public SiteType()
{
this.Sites = new HashSet<Site>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Site> Sites { get; set; }
}

现在我使用的是强类型 View ,但是我没有使用 Site 作为类型,而是使用了我创建的名为 SiteViewModel 的自定义 ViewModel,它看起来像这样......

public class SiteViewModel
{
public Site Site { get; set; }
public bool WasPosted { get; set; }
public IEnumerable<SiteType> AvailableSiteTypes { get; set; }
public IEnumerable<SiteType> SelectedSiteTypes { get; set; }
}

这样做的原因是我想使用 MVC 的 CheckBoxList 扩展,如 here 所述

现在,当我创建一个新站点并向其添加 SiteType 时一切正常,但是当我尝试编辑现有记录时,我开始遇到问题。

这是我在 Controller 中编辑 GET 方法....

    public ActionResult Edit(int id = 0)
{
Site site = _repository.GetSiteByID(id);
if (site == null)
{
return HttpNotFound();
}

var model = new SiteViewModel();
model.AvailableSiteTypes = _repository.GetSiteTypes();
model.SelectedSiteTypes = site.SiteTypes;
model.Site = site;

return View(model);
}

而 post 方法原来是这样的....

    [HttpPost]
public ActionResult Edit(SiteViewModel siteViewModel, int[] siteTypes)
{

if (ModelState.IsValid)
{
_repository.UpdateSite(siteViewModel.Site, siteTypes);
_repository.Save();
return RedirectToAction("Index");
}

siteViewModel.AvailableSiteTypes = _repository.GetSiteTypes();
List<SiteType> selectedSiteTypes = _repository.GetSiteTypes(siteTypes).ToList();
if (selectedSiteTypes.Count > 0)
{
siteViewModel.SelectedSiteTypes = selectedSiteTypes;
}
return View(siteViewModel);

}

现在我遇到的问题是 siteViewModel.Site 正在使用更新后的数据从表单中正确填充,但是 Id 列被设置为“0”,即使它是现有记录而不是新记录。我已经尝试了一切,但我无法弄清楚为什么。我能让它工作的唯一方法是接受一个“id”参数并像这样手动将它设置为 Site 对象......

HttpPost]
public ActionResult Edit(int id, SiteViewModel siteViewModel, int[] siteTypes)
{
siteViewModel.Site.Id = id;
......

但与其他所有内容结合在一起的程度相比,它感觉真的很乱。

这是唯一的方法吗?我错过了什么吗?

非常感谢您花时间阅读我的帖子。抱歉,它太长了,我不知道还能怎么解释...

最佳答案

将实际实体发送到您的 View 从来都不是一个好主意,您的 View 模型应该只获取将 View 呈现给用户所需的数据。如果您需要将有关每个 Site 的信息传递给 View ,则创建一个单独的 View 模型或 DTO 并将其传递给 View ,例如

siteViewModel.Site = new SiteDto()
{
Id = site.Id,
Name = site.Name,
...
}

实体具有隐藏属性,用于将其映射回数据库中的记录,当您将实体传入/传出 View 时,此信息通常会丢失。正确的方法是向 View 发送它需要的所有数据,仅此而已。然后在您的 POST 方法中,重新拉取您的实体并应用来自 View 模型的更改。

您可以使用 AutoMapper如果您发现自己到处都在这样做。

关于c# - MVC Controller 未绑定(bind) ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12458372/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com