【问题标题】:ActionResult<IEnumerable<T>> has to return a List<T>ActionResult<IEnumerable<T>> 必须返回 List<T>
【发布时间】:2018-08-08 08:55:14
【问题描述】:

使用 ASP.NET Core 2.1 获取以下代码:

[HttpGet("/unresolved")]
public async Task<ActionResult<IEnumerable<UnresolvedIdentity>>> GetUnresolvedIdentities()
{
   var results = await _identities.GetUnresolvedIdentities().ConfigureAwait(false);
   return results.ToList();
}

既然GetUnresolvedIdentities()返回IEnumerable&lt;UnresolvedIdentity&gt;,我会认为我可以返回

return await _identities.GetUnresolvedIdentities().ConfigureAwait(false);

除非我不能,因为我收到此错误:

CS0029 无法隐式转换类型 'System.Collections.Generic.IEnumerable&lt;Data.Infrastructure.Models.UnresolvedIdentity&gt;''Microsoft.AspNetCore.Mvc.ActionResult&lt;System.Collections.Generic.IEnumerable&lt;Data.Infrastructure.Models.UnresolvedIdentity&gt;&gt;'

我需要.ToList(),这很烦人,因为它是 2 行而不是 1 行。

为什么ActionResult&lt;T&gt; 不能确定GetUnresolvedIdentities() 返回一个IEnumerable&lt;&gt; 并直接返回?

GetUnresolvedIdentities的签名是:

Task<IEnumerable<UnresolvedIdentity>> GetUnresolvedIdentities();

【问题讨论】:

  • 因为IEnumerableIEnumerable&lt;T&gt; 不同。更改 _identities.GetUnresolvedIdentities 返回类型或您的控制器返回类型。
  • 为什么不return await _identities.GetUnresolvedIdentities().ConfigureAwait(false).ToList();,如果“两行”是唯一困扰你的事情?
  • @Corak 因为你不能task.ToList()(await task).ToList() 会起作用
  • 您可以使用 Ok 辅助方法将其包装在 ActionTask 中:return Ok(await _identities.GetUnresolvedIdentities());。附言你不应该在控制器内部调用.ConfigureAwait(false),除非你100% 确定后果(尽管现在它不像在旧版ASP.NET 中那样严重)。建议始终在 通用库 中使用它,因为它不知道该库将在哪个上下文中使用
  • 您实际上不需要在 ASP.NET Core 的任何地方使用 ConfigureAwait,因为它没有同步上下文。

标签: c# asp.net-core actionresult asp.net-core-2.1


【解决方案1】:

从 msdn 获取此文档: https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.1#actionresultt-type

C# 不支持接口上的隐式转换运算符。 因此,将接口转换为具体类型是 必须使用ActionResult&lt;T&gt;

【讨论】:

    【解决方案2】:

    您可以使用Ok(...) 以相对整洁的方式解决此问题

    [HttpGet]
    public ActionResult<IEnumerable<MyDTOObject>> Get() => Ok(Repo.GetObjects());
    
    [HttpGet]
    public async Task<ActionResult<IEnumerable<MyDTOObject>>> GetAsync() => Ok(await Repo.GetObjectsAsync());
    

    假设GetObjects()GetObjectsAsync() 分别返回IEnumerable&lt;MyDTOObject&gt;Task&lt;IEnumerable&lt;MyDTOObject&gt;&gt; - 允许您跳过.ToList().ToListAsync()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多