我正在使用.Net框架和实体框架构建REST Web API。我们正在使用OAuth 2.0授权,并且所有请求都必须具有有效的访问令牌才能使用API。
我的服务行为异常。商业服务正在做这样的事情:
Create the entity
add it to the db
generate the system comment that entity was created
add the comment to the
public void Task<MyEntity> Create(entity){
_entityRepository.Add(entity);
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
await _entityCommentBusinessService.AddSystemComment(entity, EntitySystemCommentTypes.StatusChangedNewEntity).ConfigureAwait(false);
await _bookingArtifactService.SetValidity(entity.Id).ConfigureAwait(false);
return entity;
添加系统注释会生成注释模型并调用AddComment:
public async Task<CommentModel> AddComment(CommentModel model)
{
var entity = repository.Create();
repository.Add(entity);
MapModelToEntity(model, entity);
entity.UserId = identity.UserId;
await context.SaveChangesAsync().ConfigureAwait(false);
return MapEntityToModel(entity);
}
当执行点到达SaveChangesAsync()
方法内的AddComment
时,将引发异常。
当我使用一个访问令牌实例(为了清楚起见,它没有过期)时,我得到Data exception
。
但是,如果我使用其他令牌(再次要注意的是未过期)并且操作成功完成,则不会发生此问题。
此外,如果我使用未经授权的访问令牌,则会得到未经授权的401,这是预期的行为。
我尝试将这些操作包装到TransactionScope中,但问题仍然存在。 由于注释必须按ID引用实体,因此无法避免两次保存更改。
现在,我知道dbContext并不是以最佳方式进行管理的,但是鉴于这种情况,目前无法重构它。我可以为使用该API的网站发布新的访问令牌,但我认为该解决方案无法长期有效。
答案 0 :(得分:0)
问题出在令牌生成上。我们为每个不会过期的环境发行了一些令牌(它们在大约一年后就到期了),因此我们在开发过程中不必担心这一点。但是,从一种环境发出的令牌确实可以在其他环境上使用,但这并不意味着该用户存在于数据库中。由于注释表基本上是目前我从UserId
中提取Identity
并将其保存到数据库的唯一地方,因此由于引用了不存在的外键而引发了异常。
外卖: