【发布时间】:2014-01-24 23:55:23
【问题描述】:
我正在使用 ASP.NET WebApi 2 和 Entity Framework 6.1.0-alpha1 编写一个简单的“Todo App”。我的目标是限制访问,每个用户只能查看/编辑自己的待办事项。
例子:
// GET api/Todo/5
[ResponseType(typeof(Todo))]
public async Task<IHttpActionResult> GetTodo(int id)
{
var todo = await _db.Todos.FindAsync(id);
if (todo == null)
{
return NotFound();
}
if (todo.CreatorId != _currentUser.Id)
{
return StatusCode(HttpStatusCode.Forbidden);
}
return Ok(todo);
}
没关系。为删除添加了类似的检查,并在创建时将 CreatorId 设置为当前用户的 ID。但是,我在更新时遇到了问题。
我试过了:
// PUT api/Todo/5
public async Task<IHttpActionResult> PutTodo(int id, Todo todo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != todo.Id)
{
return BadRequest();
}
// --- No exception if I remove this block - BEGIN ---
var original = await _db.Todos.FindAsync(id);
if (original.CreatorId != _currentUser.Id || original.CreatorId != todo.CreatorId)
{
return StatusCode(HttpStatusCode.Forbidden);
}
// --- No exception if I remove this block - END ---
_db.Entry(todo).State = EntityState.Modified; // Exception thrown here
try
{
await _db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
但是,System.InvalidOperationException 它抛出了标记线:
System.InvalidOperationException
附加类型为“ModernWeb.Domain.Models.Todo”的实体失败 因为另一个相同类型的实体已经有相同的主 核心价值。使用“附加”方法或设置时可能会发生这种情况 实体的状态为“未更改”或“已修改”,如果存在 该图具有冲突的键值。这可能是因为一些 实体是新的,尚未收到数据库生成的密钥 价值观。在这种情况下,使用“添加”方法或“添加”实体状态 跟踪图,然后将非新实体的状态设置为 “未更改”或“已修改”(视情况而定)。
如果我使用 FindByAsync() 删除块,它不会抛出异常。
我也尝试使用_db.Entry(todo).OriginalValue,但找不到有效的语法。
我该如何克服这个问题?对于这种情况有什么最佳做法吗?
【问题讨论】:
标签: c# entity-framework asp.net-web-api entity-framework-6 asp.net-web-api2