如何使用 System.Text.Json 库异步反序列化?

How to deserialize asynchronously using System.Text.Json library?

我有一个 json,我正在使用 NewtonSoftJson Json 库反序列化,如下所示:

public async Task InvokeAsync(HttpContext httpContext, ISchema schema)
{
    ...
    var request = Deserialize<GraphQLRequest>(httpContext.Request.Body);
    ....
}

public static T Deserialize<T>(Stream s)
{
    using (var reader = new StreamReader(s))
    using (var jsonReader = new JsonTextReader(reader))
    {
        var ser = new JsonSerializer();
        return ser.Deserialize<T>(jsonReader);
    }
}

现在我正在尝试使用 System.Text.Json 库进行异步反序列化,所以我阅读了他们的文档,他们确实有我可以使用的 DeserializeAsync 方法,但是当我像下面那样替换上述方法的内容时我收到编译错误 -

public static T Deserialize<T>(Stream s)
{
  return JsonSerializer.DeserializeAsync<GraphQLRequest>(s, new JsonSerializerOptions
      {
          PropertyNameCaseInsensitive = true
      }
  );
}

我得到的错误是 -

Cannot convert expression type 'System.Threading.Tasks.ValueTask<App.Api.Kestrel.GraphQLRequest?>' to return type 'T'

我是 dotnet 世界的新手,所以有点混淆我在这里做错了什么?

  1. public static T Deserialize<T>(Stream s)是一个generic method,其中T是用户传递的类型参数,所以你需要反序列化为T,而不是至 GraphQLRequest.

  2. 异步方法通常 (but not always) 重新运行 Task,因此您需要相应地更改签名和实现,从而导致:

public static async Task<T> Deserialize<T>(Stream s)
{
  return await JsonSerializer.DeserializeAsync<T>(s, new JsonSerializerOptions
      {
          PropertyNameCaseInsensitive = true
      }
  );
}

然后在调用中传递具体类型(并使用await):

public async Task InvokeAsync(HttpContext httpContext, ISchema schema)
{
    ...
    GraphQLRequest request = await Deserialize<GraphQLRequest>(httpContext.Request.Body);
    ....
}

因为 JsonSerializer.DeserializeAsync returns a ValueTask 另一种选择是不等待就通过它:

public static ValueTask<T> Deserialize<T>(Stream s)
{
  return JsonSerializer.DeserializeAsync<T>(s, new JsonSerializerOptions
      {
          PropertyNameCaseInsensitive = true
      }
  );
}

调用代码不会改变。