CsvReader read stream from Request Body in Asp.net core MVC occured unhandled exception.
■Exception
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware: Error: An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
[ActionName("SaveLog")]
[HttpPost]
public IActionResult SaveLog([FromHeader] HeaderDTO headerDTO)
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
//ヘッダを出力しないように指定
HasHeaderRecord = false,
};
using (var reader = new StreamReader(Request.Body))
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecords<Operationlog>().ToList();
}
return Ok();
}
You are being affected by a breaking change from ASP.NET Core 3.0.
HTTP: Synchronous IO disabled in all servers
Starting with ASP.NET Core 3.0, synchronous server operations are disabled by default.
Change description
AllowSynchronousIO is an option in each server that enables or disables synchronous IO APIs like
HttpRequest.Body.Read
,HttpResponse.Body.Write
, andStream.Flush
. These APIs have long been a source of thread starvation and app hangs. Starting in ASP.NET Core 3.0 Preview 3, these synchronous operations are disabled by default.Affected servers:
- Kestrel
- HttpSys
- IIS in-process
- TestServer
Expect errors similar to:
- Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
- Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
- Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.
Each server has an AllowSynchronousIO option that controls this behavior and the default for all of them is now false.
The package CsvHelper already addressed it ,Convert your controller method to async and just call the async equivalent of the method in CsvHelper:
[ActionName("SaveLog")]
[HttpPost]
public async Task<IActionResult> SaveLog([FromHeader] HeaderDTO headerDTO)
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
//ヘッダを出力しないように指定
HasHeaderRecord = false,
};
using (var reader = new StreamReader(Request.Body))
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecordsAsync<Operationlog>();
await foreach (var item in records)
{
//iterate through your records
}
}
return Ok();
}