基本上,我有一个表格,其中包含公司的一些属性。 这是“主”表,它们的ID在许多其他表中使用。 我基本上通过这种方法找到他们的ID:

private Company currentcompany()
    {
        Company cuco = db.Companies.Single(x => x.username == User.Identity.Name);
        return cuco;
    }

我需要让用户能够更新存储在此表中的各种有关自己的详细信息,我做得非常好 - 但是,我注意到了一个很大的安全漏洞!

在Firefox上使用篡改数据(我想象Fidler /许多其他人),我可以轻松更改隐藏的ID并修改其他公司的详细信息。

为了阻止这种情况,我在修改操作中添加了以下行:

        Company cuco = currentcompany();

        if (company.id != cuco.id)
        {
            return Content("Security Error");
        }

(仅供参考 - Company是代表公司的模型/ POCO, company本身就是表格数据。)

添加之后,如果我在表单数据中编辑ID,它会按预期工作并显示“安全错误”,但是,如果没有错误我继续,我会在问题中得到错误。

“ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象。”

我相信这是因为EF以某种方式检测并保持第一次数据拉动,但我不确定如何纠正它。

有什么建议?

编辑 - 更新 -

如果你能理解我想要实现的目标,那么有更好的解决方法吗?

#1楼 票数:150 已采纳

如果从上下文加载实体,则无法再次使用相同的键附加实体。 第一个实体仍保留在内部上下文缓存中,并且上下文只能容纳一个具有每个类型给定键值的实例(它被称为身份映射, 在其他情况下将其描述 )。

您可以通过分离前实例来解决它,但您不必这样做。 如果您只需要保存新值,可以使用:

  • ObjectContext API: context.YourEntitySet.ApplyCurrentValues(newEntity);
  • DbContext API: context.Entry(oldEntity).CurrentValues.SetValues(newEntity);

#2楼 票数:5

根据Ladislav的oldEntity ,如果您不知道如何找到oldEntity ,请为您提供一些帮助:

var entityKey = context.NewEntitySet.Create().GetType().GetProperty("Id").GetValue(newEntity);

factory.Entry(context.Set<NewEntityType>().Find(entityKey)).CurrentValues.SetValues(newEntity);

#3楼 票数:1

由于错误明确指出 - 您需要确保获取现有项目并使用更新的信息修改该项目数据并保存。 如果更新非常具体的信息而不是IDForeignKey ID等关键信息,则不会遇到此问题
下面的代码应该做的工作!

 public virtual void Update(TEntity entity)
    {
        _context.Entry(entity).State = EntityState.Modified;

        this._context.SaveChanges();
    }

用法将是 -

 public async Task<bool> UpdateVendorItem(string userId, Vendor modified)
    {

        try
        {
            var existing = await this.GetVendors().SingleOrDefaultAsync(a => a.Id == modified.Id);


            //Set updated info
            existing.VendorName = modified.VendorName;

            //Update address information
            existing.Address.AddressLine1 = modified.Address.AddressLine1;
            ... 

            await _vendorRepository.UpdateAsync(existing);

    ...

#4楼 票数:0

昨天刚看到这个问题。 您需要在更新之前分离cuco。 在这个答案中查看解决方案

  ask by Wil translate from so

未解决问题?本站智能推荐:

1回复

{“ ObjectStateManager中已经存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象。”}

我有此代码,但出现异常 具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象。 在其他部分。
10回复

具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象

尝试将EF5与通用存储库模式结合使用,并使用ninject进行依赖关系注入,并尝试使用带有edmx的存储过程将实体更新到数据库时遇到问题。 我在DbContextRepository.cs中的更新是: 从我的AddressService.cs返回到我的存储库,我有: 当它遇
6回复

具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象

我有以下代码来添加或更新Entity对象。 根据我要添加或更新对象的响应,通过主键查找对象。 添加记录是可行的,但是在更新过程中会给出此错误消息“ ObjectStateManager中已经存在具有相同键的对象。ObjectStateManager无法跟踪具有相同键的多个对象” 在
1回复

具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象

我有以下EdiePOST操作方法: 在哪里repository.UpdateVisit(visit); 是:- 但是,当我运行我的应用程序并尝试编辑访问对象时,出现以下错误:- 在repository.UpdateVisit(visit);上repository.Upd
1回复

错误:ObjectStateManager中已经存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象

我是实体框架的新手。 在问这个问题之前,我已经在这个网站和google上搜索过,到处都找到了不同的答案。 但是我的问题没有解决,所以我问这个问题。 我在尝试删除记录时收到上述错误。 这是我的代码: 这是表之间的关系: 注意:请注意,级联删除在SQL Serve
1回复

错误:ObjectStateManager中已经存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象

我是EF的初学者,正在开发其他代码。 通用存储库类具有以下更新方法 这个方法叫做 修改SearchLog后,我调用searchLogRepository.Update(toUpdate),但收到此错误 “ ObjectStateManager中已经存在具有相同键的对象。O
2回复

具有相同键的对象已存在于ObjectStateManager中

无法将多对多属性保存到数据库。 错误详情: 具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象。 我试图在此操作方法中保存属性: 数据库表结构是这样的: 3桌 userR
1回复

具有相同键的对象已存在于objectstatemanager中。

使用实体框架更新两个表时出现以下错误- 具有相同键的对象已存在于objectstatemanager中。 现有对象处于修改状态。 如果对象处于添加状态,则只能将其再次添加到objectstatemanager 我的密码