其他分享
首页 > 其他分享> > CVC-MVC控制器未绑定ViewModels

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