In previous article, we have explained how to troubleshoot 403 error when publishing ASP.NET Core and 502.5 error when publishing ASP.NET Core. If you have’t read that article, you may check it out.
ASP.NET Core always keep up to date their version and we always follow and testing their newest version. Soon, Microsoft will release newest ASP.NET Core 3. But, don’t discuss it first and still in development mode.
We have been working and testing this ASP.NET Core 2.2 since it was released. We always testing on getting all our different applications updated and using in-process hosting. In this test, we use SQLLite and when the application tried to access the database, we received this error:
SqliteException: SQLite Error 14: ‘unable to open database file’. Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(int rc, sqlite3 db) Microsoft.Data.Sqlite.SqliteConnection.Open() Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(bool errorsExpected)
What is the Issue?
After googling, we found an issue on Github that discuss the problem. It turns out that when the application gets its current directory it is returning the path to the IIS process that is hosting the application instead of the directory when the application is.
How to Fix the Error?
We found another link on Github and we need to add following class in your application. Please check the code below:
internal class CurrentDirectoryHelpers
{
internal const string AspNetCoreModuleDll = "aspnetcorev2_inprocess.dll";
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[System.Runtime.InteropServices.DllImport(AspNetCoreModuleDll)]
private static extern int http_get_application_properties(ref IISConfigurationData iiConfigData);
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
private struct IISConfigurationData
{
public IntPtr pNativeApplication;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
public string pwzFullApplicationPath;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)]
public string pwzVirtualApplicationPath;
public bool fWindowsAuthEnabled;
public bool fBasicAuthEnabled;
public bool fAnonymousAuthEnable;
}
public static void SetCurrentDirectory()
{
try
{
// Check if physical path was provided by ANCM
var sitePhysicalPath = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_PHYSICAL_PATH");
if (string.IsNullOrEmpty(sitePhysicalPath))
{
// Skip if not running ANCM InProcess
if (GetModuleHandle(AspNetCoreModuleDll) == IntPtr.Zero)
{
return;
}
IISConfigurationData configurationData = default(IISConfigurationData);
if (http_get_application_properties(ref configurationData) != 0)
{
return;
}
sitePhysicalPath = configurationData.pwzFullApplicationPath;
}
Environment.CurrentDirectory = sitePhysicalPath;
}
catch
{
// ignore
}
}
}
Finally, in the Main function of the Program class add the following line as the first thing in the function.
CurrentDirectoryHelpers.SetCurrentDirectory();
Wrapping Up
With the above changes, all will work as expected. It is my understanding that this issue will be addressed at some point in the future as a patch so this should just be a temporary fix.