Fix error System.lnvalidOperationException: Synchronous operations are disallowed

  • Updated

This article is only applicable for CMS 12, Commerce Connect 14.

Symptoms

The exception System.lnvalidOperationException happens sporadically when working in CMS or Commerce Connect UI. It often occurs when an editor tries to expand a content/product node with lots of children items.

Sample error stack trace:

System.InvalidOperationException: Synchronous operations are disallowed, Call WriteAsync or set AllowSynchronouslO 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[] buffer, Int32 offset, Int32 count)
at MicrosoftAspNetCore.ResponseCompression.ResponseCompressicnBody.Write(Byte[] buffer, Int32 offset, Int32 count)
at MicrosoftAspNetCore.WebUtilities.HttpResponseStreamWrfter.Write(String value)
at NewtonsoftJson.JsonTextWriter.WritePropertyName(String name, Boolean escape)

 

Explanation

In some cases, the size of data is large and Newtonsoft.Json has to stream the serialized data to the client-side by using a StreamWriter. That requires the hosting service (Kestrel) to allow synchronous read/write operations.

Due to a bug of NetCore, AllowSynchronousIO is set to "false" by default from NetCore 3 (see reference).

 

Fix and mitigation

 

  1. Replace Newtonsoft.Json implementation with System.Text.Json serialization. The CMS will use System.Text.Json serialization by default. 

 

  1. Update CMS Core and Newtonsoft.Json to latest version.
  2. Enable AllowSynchronousIO in code:

Option 1: Program.Main() entry-point

public static void Main(string[] args) => Host.CreateDefaultBuilder(args)
.ConfigureCmsDefaults()
.ConfigureWebHostDefaults(webBuilder => webBuilder
.UseKestrel(options => options.AllowSynchronousIO = true)
.UseStartup<Startup>())
.Build().Run();

 

Option 2: Startup.ConfigureServices() method

services.Configure<KestrelServerOptions>(options => 
{
options.AllowSynchronousIO = true;
});

 

Remarks