C# 返回任务<;T>;因为普通任务破坏了WebAPI

C# 返回任务<;T>;因为普通任务破坏了WebAPI,c#,asp.net-web-api,async-await,C#,Asp.net Web Api,Async Await,在这个问题上,这实际上是一个不同的角度 考虑一下这个代码 public interface IQueryHandler<in TQuery, TResult> where TQuery : Query<TResult> { Task<TResult> Handle(TQuery query); } WebApi控制器 public Task Get([FromUri] Contract contract) { return _invoker

在这个问题上,这实际上是一个不同的角度

考虑一下这个代码

public interface IQueryHandler<in TQuery, TResult> where TQuery : Query<TResult>
{
    Task<TResult> Handle(TQuery query);
}
WebApi控制器

public Task Get([FromUri] Contract contract)
{
    return _invoker.Invoke(CreateDto<Query>(contract));
}
公共任务获取([FromUri]合同)
{
返回_invoker.Invoke(CreateDto(contract));
}

这将破坏WebAPI,并且由于某种原因,响应会将我重定向到站点的基本url

您得到的是重定向响应而不是204,这看起来确实很奇怪,但无论哪种方式,您的操作方法都不会像您期望的那样使用该方法签名。通过返回
任务
,您实际上是在告诉框架您希望(异步)不返回任何内容

我知道您不知道运行时任务中的
t
,解决方法是等待结果并将其强制转换为对象。这应该起作用:

public async Task<object> Get([FromUri] Contract contract)
{
    var result = await _invoker.Invoke(CreateDto<Query>(contract));
    return result as object;
}
公共异步任务Get([FromUri]契约)
{
var result=await_invoker.Invoke(CreateDto(contract));
将结果作为对象返回;
}

奇怪的是,你被重定向了。您实际上返回了void(异步),这将导致204(无内容)。你确定这个动作会被击中吗?可以通过在
Get
方法中放置断点并从调试器中命中它来进行验证。是的,它同时从Queryhandler和Get methodYes中命中,但在支持诸如“public dynamic GetFoo(){}之类声明的框架中你确实希望它能把一个任务分解成一个任务:D它确实有很多automagic用于其他东西,比如提到的动态,但也有JObject>静态类型等。看起来很奇怪,它在这里不起作用。我觉得在另一个异步任务中使用它不是很有效。我不同意这种期望。众所周知,返回
void
Task
是向框架明确表示希望返回无内容响应的方式。完全从方法签名(而不是实现)推断出我的意图可以保持事情的可预测性和一致性。像这样的怪癖一直在发生,另一个例子是Linq Count。它检查IEnumerable是否是一个列表,如果是这种情况,则使用Count属性。不过这不是一个怪癖。返回
Task
是一种明确的机制,用于告诉框架您希望响应主体为空。如果没有,则只需返回
Task
Task
,如我所示。我不确定我是否理解你的反对意见。IEnumerable是列出任务与任务之间的关系(超集)
public async Task<object> Get([FromUri] Contract contract)
{
    var result = await _invoker.Invoke(CreateDto<Query>(contract));
    return result as object;
}