【问题标题】:Web API - Interceptor - intercepting async controller actionsWeb API - 拦截器 - 拦截异步控制器操作
【发布时间】:2018-03-31 05:18:39
【问题描述】:

在我们的 Web API 集成测试中,我们在测试异步操作时遇到了问题。

在我的简单测试中,我创建了一个简单的控制器动作:

[HttpGet]
[Route("test")]
public async Task<ApiResponse> Test()
{
    return await Task.FromResult(new ApiResponse(true));
}

但是,当我运行集成测试时,它会因以下异常而失败:

System.InvalidCastException:无法转换类型的对象 'Jacobo.Api.Model.Shared.ApiModels.ApiResponse' 输入 'System.Threading.Tasks.Task`1 [Jacobo.Api.Model.Shared.ApiModels.ApiResponse]'。 在 Castle.Proxies.IIdentityControllerProxy.Test() 在 ServerApi.IntegrationTests.IdentityControllerTests.d__10.MoveNext() 在 E:\Dev\Jacobo\ServerApi.IntegrationTests\IdentityControllerTests.cs:line 218 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 NUnit.Framework.Internal.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(对象 调用结果)在 NUnit.Framework.Internal.Commands.TestMethodCommand.RunAsyncTestMethod(TestExecutionContext 上下文)

我可以看到这是从哪里来的,因为我们返回的结果不再匹配显然包含在任务中的操作返回类型。

我们的拦截器代码的整个块运行良好:

public void Intercept(IInvocation invocation)
{
    // our interceptor implementation ...
    // some irrelevant code before this
    invocation.ReturnValue = webInvocation.Invoke(_client, invocation.Arguments); // the return value is populated correctly. not wrapped in a task.
}

然后测试失败,因为它试图返回等待的结果:

[Test]
public async Task GettingAsyncActionResultWillSucceed()
{
    var ctl = BuildController(new SameMethodStack("GET"));
    var result = await ctl.Test();
    Assert.IsTrue(result.Success);
}

我很不确定从这里去哪里。

【问题讨论】:

    标签: c# async-await asp.net-web-api2 interceptor castle-dynamicproxy


    【解决方案1】:

    终于找到了解决办法。我必须检测该方法是否是异步的,并在此基础上将结果包装到一个任务中:

    if (isAsync)
                {
                    var result = webInvocation.Invoke(_client, invocation.Arguments);
                    var type = result.GetType();
                    var methodInfo = typeof(Task).GetMethod("FromResult");
                    var genericMethod = methodInfo.MakeGenericMethod(type);
                    invocation.ReturnValue = genericMethod.Invoke(result, new []{ result });
                }
    

    【讨论】:

      猜你喜欢
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 2016-08-31
      • 1970-01-01
      • 2014-03-10
      • 2021-09-04
      相关资源
      最近更新 更多