Klicke hier für den deutschen Artikel.
Symptom
If a pre-assigned project is to be loaded when starting the Web Designer (Windows desktop version), this does not work and the project wizard for a new project is started instead.
However, the identical project can be successfully loaded and used in both the Web Report Designer and the Web Report Viewer. In a Debwin log file, the following is displayed symptomatically:
...
[clsLoadManagerThread] RemoteRepository: LoadItem('repository://{XXXXXXXX-XXXXXX-XXXXXX-XXXXXXXXX}')
[clsLoadManagerThread] RemoteRepository: **Received 0 bytes**
=0;file 'repository://{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX}' exists, and is empty. I assume I shall use this...
-22 (FFFFFFEA) ( **No project exists with the specified file name.** )
...
Cause
In previous programming examples we show a SQLite-based repository implementation with synchronous I/O operations.
When using “pure” Kestrel, i.e. without a proxy for the requests, this error can occur because the .NET Core (Kestrel) web hosting only supports asynchronous operations (I/O) by default (see KestrelServerOptions.AllowSynchronousIO property).
This setting is standard with Microsoft, as a large number of blocking synchronous I/O operations can lead to a lack of resources in the thread pool. For more information, see Configuring options for the ASP.NET Core-Kestrel web server.
Solution
Solution 1
Adapt the repository implementation for LoadItem() to asynchronous requests - here using the supplied example SQLiteFileRepository.cs:
...
public void LoadItem(string itemID, Stream destinationStream, CancellationToken cancelToken)
{
object fileContent = _db.CreateCommand(
"SELECT FileContent FROM RepoItems WHERE ItemID = @ItemID")
.SetParameter("ItemID", itemID).ExecuteScalar();
byte[] content = new byte[0];
if (fileContent is byte[] byteContent)
{
content = byteContent;
}
destinationStream.Write(content, 0, content.Length);
}
...
replaced by:
...
public void LoadItem(string itemID, Stream destinationStream, CancellationToken cancelToken)
{
object fileContent = _db.CreateCommand(
"SELECT FileContent FROM RepoItems WHERE ItemID = @ItemID")
.SetParameter("ItemID", itemID).ExecuteScalar();
byte[] content = new byte[0];
if (fileContent is byte[] byteContent)
{
content = byteContent;
}
destinationStream
.WriteAsync(content, 0, content.Length, cancelToken)
.GetAwaiter()
.GetResult();
}
...
Solution 2
Alternatively, you can run the requests through a different web hosting environment instead, e.g. IIS (Internet Information Services) or IIS Express. IIS often manages the synchronization context more strictly, which can sometimes “fix” problems with code that is not fully optimized for asynchronous operations.
Solution 3
Another option is to configure Kestrel for synchronous I/O operations. The following example enables synchronous I/O operations:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.AllowSynchronousIO = true;
});
For more information, see Configuring options for the ASP.NET Core-Kestrel web server.
Attention: This can lead to the above-mentioned lack of resources!