从DB填充对象后获取EntityValidationErrors

时间:2014-11-09 21:02:50

标签: asp.net-mvc repository-pattern entity-framework-6

我的ASP.NET MVC应用程序中的编辑操作有问题。

我想用ViewModel数据更新我的实体。

这是我的行动代码:

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ConferenceViewModel conferenceViewModel, int id)
{
    if (ModelState.IsValid)
    {
        var tags = await AddOrUpdateTags(conferenceViewModel.TagNames);
        Conference conference = await repo.ConferenceRepo.GetByID(id);
        Mapper.Map<ConferenceViewModel, Conference>(conferenceViewModel, conference);

        conference.Tags = tags;
        conference.ApproxLocation = await repo.ApproxLocationRepo.GetByID(conferenceViewModel.ApproxLocation_Id);
        conference.ExactLocation = await repo.ExactLocationRepo.GetByID(conferenceViewModel.ExactLocation_Id);
        repo.ConferenceRepo.Update(conference);
        await repo.SaveAsync();
        return RedirectToAction("Index");
    }

    return View(conferenceViewModel);
}

标签更新方法:

    private async Task<List<Tag>> AddOrUpdateTags(string tags, bool save = true)
    {
        string[] tagNames = tags.Split(',');
        List<Tag> tagEntities = new List<Tag>();

        foreach (string tag in tagNames)
        {
            Tag existingTag = (await repo.TagRepo.Get(t => t.Name == tag)).FirstOrDefault();

            if (existingTag == null)
            {
                tagEntities.Add(
                    repo.TagRepo.Insert(new Tag { Name = tag })
                );
            }
            else
            {
                tagEntities.Add(existingTag);
            }
        }
        if (save)
            await repo.SaveAsync();

        return tagEntities;
    }

AutoMapper地图在构造函数中创建:

Mapper.CreateMap<ConferenceViewModel, Conference>()
            .ForMember(x => x.Creator, opt => opt.Ignore())
            .ForMember(x => x.DateCreated, opt => opt.Ignore())
            .ForMember(x => x.Reservations, opt => opt.Ignore())
            .ForMember(x => x.Speakers, opt => opt.Ignore())
            .ForMember(x => x.ConferenceId, opt => opt.Ignore());

我正在使用存储库模式和Update方法,如下所示:

public virtual TEntity Update(TEntity entityToUpdate)
{
    var entry = context.Entry<TEntity>(entityToUpdate);

    if (entry.State == EntityState.Detached)
    {
        context.Set<TEntity>().Attach(entityToUpdate);
        entry.State = EntityState.Modified;
    }

    return context.Entry(entityToUpdate).Entity;
}

当我发布完整表格时,我得到了这个(从这里得到它:EF Code First: How do I see 'EntityValidationErrors' property from the nuget package console?):

[DbEntityValidationException: Entity Validation Failed - errors follow:
DroConf.Entities.ApproxLocation failed validation
- City : The City field is required.
- Country : The Country field is required.
DroConf.Entities.ExactLocation failed validation
- Street : The Street field is required.
- BuildingNo : The BuildingNo field is required.
- City : The City field is required.
- Country : The Country field is required.
]

看起来动作方法中的代码没有正确更新导航属性,但我不知道为什么。有什么建议吗?

=====================================

解: 它适用于以下代码:

[Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit(ConferenceViewModel conferenceViewModel, int id)
    {
        if (ModelState.IsValid)
        {
            conferenceViewModel.ApproxLocation = await repo.ApproxLocationRepo.GetByID(conferenceViewModel.ApproxLocation_Id);
            conferenceViewModel.ExactLocation = await repo.ExactLocationRepo.GetByID(conferenceViewModel.ExactLocation_Id);

            var tags = await AddOrUpdateTags(conferenceViewModel.TagNames, true);

            Conference conference = await repo.ConferenceRepo.GetByID(id);
            Mapper.Map<ConferenceViewModel, Conference>(conferenceViewModel, conference);
            conference.Tags.Clear();
            conference.Tags = tags;

            repo.ConferenceRepo.Update(conference);
            await repo.SaveAsync();

            return RedirectToAction("Index");
        }

        return View(conferenceViewModel);
    }

ConferenceViewModel有一个名为ApproxLocationExactLocation的参考属性(与会议模型中的名称相同)。我没有在构造函数中忽略它们,它们在ConferenceViewModel中null并通过mapper传递给Conference模型。 我仍然不知道为什么我不能手动覆盖它们,但是这样它们被正确映射,因为它们存在&#39;在VM。

0 个答案:

没有答案