4

我有一个 WebApi 方法或多或少看起来像这样:

public async Task<HttpResponseMessage> Get(Guid id)
{
    var foo = await Store.GetFooAsync(id);
    if (foo.BelongsTo != User.Identity.Name)
        throw new HttpResponseException(HttpStatusCode.Forbidden);
    //return foo here
}

这似乎在实际应用程序中运行良好,其中自定义设置了和IHttpModule中的主体。HttpContext.UserThread.CurrentPrincipal

但是,从单元测试调用时:

Thread.CurrentPrincipal = principal;
var response = controller.Get(id).Result;

Userawait之后(即继续)重置,因此测试失败。在 R#8 下运行时会发生这种情况,而 R#7 不会发生这种情况。

我的解决方法是在第一次等待之前保存当前的主体,但这只是满足测试运行器需求的一种技巧。

如何调用我的控制器方法并确保延续与原始调用具有相同的主体?

4

2 回答 2

1

我通过升级 MVC 包解决了这个问题。新版本将主体保留在 中ApiController.RequestContext.Principal,与 分开Thread.CurrentPrincipal,完全避免了该问题。

我的新测试代码以:

controller.RequestContext.Principal = principal;
于 2013-10-22T15:38:56.727 回答
0

简短的版本是,使用 HttpContext.Current.Use 而不是 Thread.Principal。

简短的版本是,使用Request.LogonUserIdentityRequest.RequestContext .HttpContext.User。

async/await保留原始请求上下文,而不是启动该方法的线程。这是有道理的,否则 ASP.NET 将不得不冻结线程并使其在await返回时可用。您运行await的线程是来自 ThreadPool 的线程,因此修改其 CurrentPrincipal 是一个非常糟糕的主意。

查看Scott Hanselman 的播客“所有 .NET 程序员对异步编程的了解都是错误的”的文字记录以获取更多信息。

于 2013-10-18T12:36:42.967 回答