1

我将 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();

这个逻辑应该去哪里?开始请求部分似乎可以由请求过滤器处理,但我不相信这是最好的地方。应该在哪里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);
}

查看源代码ServiceRunner,似乎OnBeforeExecute/OnAfterExecute应该在同一个线程上运行。有什么理由这行不通吗?

4

1 回答 1

1

我会考虑使用 ServiceSTack 的IHttpRequest.Items 字典。这个字典几乎在任何请求可用的地方都可用,包括请求和响应过滤器。您可以存储您的范围并在需要时检索它。

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

于 2013-07-26T01:41:12.697 回答