CVC-MVC控制器未绑定ViewModels
作者:互联网
我希望您能为我提供帮助,因为我对MVC和Entity Framework还是陌生的,所以我想尽一切办法.我正在使用MVC4和EF5.
这是我正在尝试做的概述…
我有两个实体,Site和SiteType.每个站点可以具有多个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
06001
现在我使用的是强类型视图,但是不是使用Site作为类型,而是使用我创建的自定义ViewModel(称为SiteViewModel),它看起来像这样…
06002
原因是我想使用MVC的CheckBoxList扩展,如here所述
现在,当我创建一个新网站并向其中添加SiteType时,所有内容都可以使用,但是当我尝试编辑现有记录时,我开始遇到问题.
这是我在控制器中的编辑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;
......
但是,与其他所有内容绑定在一起的方式相比,这确实让人感到非常混乱.
这是唯一的方法吗?我想念什么吗?
非常感谢您抽出宝贵的时间阅读我的帖子.抱歉,时间太长,我不知道该怎么解释…
解决方法:
将实际的实体发送到您的视图从来都不是一个好主意,您的视图模型应该只获取将视图呈现给用户所需的数据.如果您需要将有关每个站点的信息传递给视图,请创建一个单独的视图模型或DTO,然后将其传递给例如
siteViewModel.Site = new SiteDto()
{
Id = site.Id,
Name = site.Name,
...
}
实体具有隐藏的属性,这些属性用于将其映射回数据库中的记录,当您将实体传递到视图或从视图传递时,此信息通常会丢失.正确的方法是发送视图所需的所有数据,仅此而已.然后在POST方法中,重新拉动您的实体并应用视图模型中的更改.
如果发现自己到处都在执行此操作,则可以使用AutoMapper.
标签:asp-net-mvc-4,c,asp-net-mvc,entity-framework 来源: https://codeday.me/bug/20191127/2075681.html