根据请求在同一个线程上创建/部署用户范围

时间:2013-07-24 21:14:01

标签: web-services servicestack

我正在使用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应该在同一个线程上运行。这有什么理由不起作用?

1 个答案:

答案 0 :(得分:1)

我会研究使用ServiceSTack的 IHttpRequest.Items字典。几乎在请求可用的任何地方都可以使用此词典,包括请求和响应过滤器。您可以存储示波器并在需要时检索它。

对于相同的线程问题,您不能保证整个请求将在同一个线程中发生。请参阅https://stackoverflow.com/a/1644015/215502如果您担心使用asp.net进行线程化,我会很想您可能会过度设计一些但很难说而不知道您想要做什么。