我正在尝试使用开箱即用的 ServiceStack 身份验证插件以及 RavenDB 和 RavenUserAuthRepository 包。
应用主机
var store = new DocumentStore()
{
ConnectionStringName = "ServiceStackAuthSample"
}
.Initialize();
IndexCreation.CreateIndexes(typeof(RavenUserAuthRepository).Assembly, store);
container.Register(store);
var session = container.Resolve<IDocumentStore>().OpenSession();
container.Register(p => session).ReusedWithin(ReuseScope.Request);
container.Register<IUserAuthRepository>(p => new RavenUserAuthRepository(p.Resolve<IDocumentStore>(), p.Resolve<IDocumentSession>()));
通过 Facebook、GoogleOAuth、Twitter 进行的第一次身份验证尝试按预期工作。但是,如果我尝试重新进行身份验证,RavenDB 似乎不喜欢它,我得到以下信息:
错误 CodeNonUniqueObjectExceptionmessageAttempted to associate a different object with id 'UserAuths/1'.stack Trace[Auth: 10/21/2013 6:51:04 PM]: [REQUEST: {provider:facebook}] Raven.Client.Exceptions.NonUniqueObjectException:尝试将不同的对象与 id 'UserAuths/1' 相关联。在 Raven.Client.Document.InMemoryDocumentSessionOperations.AssertNoNonUniqueInstance(Object entity, String id) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:Raven.Client.Document.InMemoryDocumentSessionOperations 的第 778 行。 StoreInternal(Object entity, Etag etag, String id, Boolean forceConcurrencyCheck) 在 c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:Raven.Client.Document.InMemoryDocumentSessionOperations 的第 670 行。
2 authInfo) at ServiceStack.ServiceInterface.Auth.FacebookAuthProvider.Authenticate(IServiceBase authService, IAuthSession session, Auth request) at ServiceStack.ServiceInterface.Auth.AuthService.Authenticate(Auth request, String provider, IAuthSession session, IAuthProvider oAuthConfig) at ServiceStack.ServiceInterface.Auth.AuthService.Post(Auth request) at lambda_method(Closure , Object , Object ) at ServiceStack.ServiceHost.ServiceRunner
1.Execute(IRequestContext requestContext, Object instance, TRequest request)
RavenDB 搜索告诉我这可能与我的会话有关,但我不确定我在这里做错了什么。这可能是我对如何在 ServiceStack 中管理 RavenDB 会话的理解。
更新
事实证明,ServiceStack.AuthenticationRavenDb.RavenUserAuthRepository::GetUserAuth方法的 v3 分支中存在错误。当所有其他方法都使用由构造函数注入的私有 IDocumentSession 成员时,GetUserAuth 正在创建一个全新的 IDocumentSession 实例。
private readonly IDocumentStore _documentStore;
public RavenUserAuthRepository(IDocumentStore documentStore,IDocumentSession session)
{
_documentStore = documentStore;
_session = session;
}
老的
public UserAuth GetUserAuth(string userAuthId)
{
using (var session = documentStore.OpenSession())
{
int intAuthId;
return int.TryParse(userAuthId, out intAuthId)
? session.Load<UserAuth>(intAuthId)
: session.Load<UserAuth>(userAuthId);
}
}
固定的
public UserAuth GetUserAuth(string userAuthId)
{
using (_session)
{
int intAuthId;
return int.TryParse(userAuthId, out intAuthId)
? _session.Load<UserAuth>(intAuthId)
: _session.Load<UserAuth>(userAuthId);
}
}
这导致CreateOrMergeAuthSession使用一个会话实例(通过 GetUserAuth)获取 UserAuth,然后使用私有会话成员保存 UserAuth,从而导致冲突。
谢谢你的提示,大卫!