带有 .NET Core 3.0 的 ServiceStack 5 似乎不起作用

ServiceStack 5 with .NET Core 3.0 doesnt seem to work

不确定其他人是否遇到过这个问题。

我有一个非常简单的 ServiceStack 服务

public VersionResponse Get(VersionRequest request)
{
   Assembly assembly = Assembly.GetExecutingAssembly();
   FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
   return new VersionResponse() { Version = fvi.FileVersion };
}

在servicestack中是这样注册的

appHost.Routes.Add<VersionRequest> ("/api/version");
appHost.RegisterService<CoreService>();

这一直有效,但在升级到 .NET Core 3.0 并根据 Microsoft 的说明更改为使用 Host Builder 后,当 ServiceStack 尝试将响应序列化为 JSON 或其他内容时,它会引发异常。

这是我们在后端遇到的错误(对图像表示歉意,但我认为很明显 ServiceStack + .NET Core 3.0 集成中出现了问题)

fail: ServiceStack.HttpResponseExtensionsInternal[0]
      Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Compression.DeflateStream.WriteDeflaterOutput()
   at System.IO.Compression.DeflateStream.WriteCore(ReadOnlySpan`1 buffer)
   at System.IO.Compression.DeflateStream.Write(Byte[] array, Int32 offset, Int32 count)
   at System.IO.Compression.GZipStream.Write(Byte[] array, Int32 offset, Int32 count)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionBody.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
   at System.IO.StreamWriter.Flush()
   at ServiceStack.Text.JsonSerializer.SerializeToStream(Object value, Type type, Stream stream) in C:\BuildAgent\work2418dcce86a188\src\ServiceStack.Text\JsonSerializer.cs:line 181
   at ServiceStack.Text.JsonSerializer.SerializeToStream[T](T value, Stream stream) in C:\BuildAgent\work2418dcce86a188\src\ServiceStack.Text\JsonSerializer.cs:line 174
   at ServiceStack.Serialization.JsonDataContractSerializer.SerializeToStream[T](T obj, Stream stream) in C:\BuildAgent\work81147c480f4a2f\src\ServiceStack.Client\Serialization\JsonDataContractSerializer.cs:line 64
   at ServiceStack.Host.ContentTypes.<>c.<.ctor>b__36_0(IRequest r, Object o, Stream s) in C:\BuildAgent\work81147c480f4a2f\src\ServiceStack\Host\ContentTypes.cs:line 20
   at ServiceStack.Host.ContentTypes.<>c__DisplayClass30_0.<GetStreamSerializerAsync>b__0(IRequest httpReq, Object dto, Stream stream) in C:\BuildAgent\work81147c480f4a2f\src\ServiceStack\Host\ContentTypes.cs:line 273
   at ServiceStack.HttpResponseExtensionsInternal.WriteToResponse(IResponse response, Object result, StreamSerializerDelegateAsync defaultAction, IRequest request, Byte[] bodyPrefix, Byte[] bodySuffix, CancellationToken token) in C:\BuildAgent\work81147c480f4a2f\src\ServiceStack\HttpResponseExtensionsInternal.cs:line 323

有人遇到这个问题吗?

ServiceStack 在 v5.7. The first major fix 中添加了与 .NET Core 3 的兼容性似乎是相关的:

Sync writes disabled by default

The primary issue in supporting .NET Core 3 was accommodating its decision to disable sync Stream writes by default, in-effect disallowing most .NET Serializers from being able to write directly to the Response OutputStream. To work around this, in .NET Core 3 all sync serializers are first written to a pooled MemoryStream before being asynchronously written to the Response’s Output Stream.

Essentially all Content Type Serializers (i.e. Serialization Formats) used in ServiceStack other than HTML View Engines (Razor/Markdown/JSON Report) and #Script Pages (written from ground-up to support async writes) are currently buffered in .NET Core 3. (we’ll look into extending native async serialization support to our own serializers in a future release).

.NET Core 3 does allow you to turn off this restriction on a per-request basis which can be controlled by turning off buffering of sync serializers with:

SetConfig(new HostConfig {
    BufferSyncSerializers = false,
})

Which restores the existing behavior to .NET Core 3 of serializing directly to the Output Stream and marking the request with AllowSynchronousIO=true.

这也是异常所讨论的内容:

Synchronous operations are disallowed. Call WriteAsync or 
set AllowSynchronousIO to true instead.