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).

 

Fixes and mitigation

  • Replace Newtonsoft.Json implementation with System.Text.Json serialization. The CMS will use System.Text.Json serialization by default. There are two scenarios that leads to Newtonsoft being registered as the preferred formatter, even for CMS UI assemblies:
    • A non-system module's config file explicitly specifying preferredUiJsonSerializerType=Newtonsoft.
    • A non-system module's config lists an assembly that contains at least on type inheriting Newtonsoft.Json.JsonConverter AND ALSO specifies preferredUiJsonSerializerType=Resolve (which is also the default value that is used if the preferredUiJsonSerializerType attribute is not explicitly included).

      Note: also check your module.config for typos -- it is case sensitive

  • Enable AllowSynchronousIO  (WARNING: Not recommended due to potential performance issues)
    • Update CMS Core and Newtonsoft.Json to latest version.
    • 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