我正在使用ServiceStack与ASP.NET Web表单和表单身份验证。每次服务呼叫我需要以下逻辑:
//-- on 'Begin Request' --
var identity = HttpContext.Current.User.Identity;
if (!identity.IsAuthenticated)
throw new UnauthorizedAccessException();
var user = //lookup user in Db using identity.Name
new UserScope(user) //store this somewhere(?)
//-- on 'End Request' --
var scope = //get user scope
scope.Dispose();
这个逻辑应该去哪里? Begin Request 部分似乎可以由请求过滤器处理,但我不相信这是最好的地方。 UserScope
应该在哪里存储和处理?它必须在同一个线程上创建和处理。
我已将ServiceRunner<TRequest>
分组并覆盖OnBeforeExecute
/ OnAfterExecute
。
public override void OnBeforeExecute(IRequestContext requestContext, TRequest request) {
if (!IsLoginRequest()) {
var identity = HttpContext.Current.User.Identity;
if (identity.IsAuthenticated) {
var user = User.GetByUserName(identity.Name);
if (user != null) {
requestContext.SetItem(USER_SCOPE_KEY, new UserScope(user));
return;
}
}
throw new UnauthorizedAccessException();
}
}
public override object OnAfterExecute(IRequestContext requestContext, object response) {
if (!IsLoginRequest()) {
var userScope = (UserScope)requestContext.GetItem(USER_SCOPE_KEY);
if (userScope != null)
userScope.Dispose();
}
return response;
}
并覆盖AppHost.CreateServiceRunner
:
public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext) {
return new MyServiceRunner<TRequest>(this, actionContext);
}
查看source for ServiceRunner
,似乎OnBeforeExecute
/ OnAfterExecute
应该在同一个线程上运行。这有什么理由不起作用?
答案 0 :(得分:1)
我会研究使用ServiceSTack的 IHttpRequest.Items字典。几乎在请求可用的任何地方都可以使用此词典,包括请求和响应过滤器。您可以存储示波器并在需要时检索它。
对于相同的线程问题,您不能保证整个请求将在同一个线程中发生。请参阅https://stackoverflow.com/a/1644015/215502如果您担心使用asp.net进行线程化,我会很想您可能会过度设计一些但很难说而不知道您想要做什么。