From d602672a1b702bdeb5560c8638f2b7adf3fcb107 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 8 Apr 2026 11:09:06 -0700 Subject: [PATCH 1/6] Use assembly name of global.asax type as default IHostEnvironment.ApplicationName There are a lot of assumptions that the ApplicationName is actually the assembly name and cause some things (like user secrets) to break if it is not. Since there's no direct way to get the main assembly directly, this sets it by searching the current HttpApplication as a best effort for this. --- .../ConfigurationManagerConfigExtensions.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs index 1afc3a4eb..5a5ecfdac 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs @@ -1,9 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.CodeDom.Compiler; using System.Collections; using System.Configuration; using System.Diagnostics; +using System.Reflection; +using System.Web; +using System.Web.Compilation; using System.Web.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Memory; @@ -50,7 +54,7 @@ public static IConfigurationManager UseHostingEnvironmentFallback(this IConfigur if (configuration[HostDefaults.ApplicationKey] is null) { optionList = new(); - optionList.Add(new KeyValuePair(HostDefaults.ApplicationKey, HostingEnvironment.SiteName)); + optionList.Add(new KeyValuePair(HostDefaults.ApplicationKey, GetExecutingAssemblyName())); } if (configuration[HostDefaults.EnvironmentKey] is null && (HostingEnvironment.IsDevelopmentEnvironment || IsIISExpress())) @@ -79,4 +83,22 @@ static bool IsIISExpress() return configuration; } + + /// + /// Does a best effort to get the the name of the assembly that was launched. This matches ASP.NET Core and allows things like UserSecrets to work. + /// + private static string GetExecutingAssemblyName() + { + // This is available in the startup even though we don't have a current request + var type = HttpContext.Current.ApplicationInstance.GetType(); + + // The ApplicationInstance may be a custom one generated by ASP.NET, so we need to walk up until we find the real one. + // The generated ones are marked with the GeneratedCodeAttribute, so we can check for that. + while (type.Assembly.GetCustomAttribute() is { } && type.BaseType.GetType() != typeof(HttpApplication)) + { + type = type.BaseType; + } + + return type.Assembly.GetName().Name; + } } From 1d8b0a35f8edd9b80731b3828d6eb186d44e1520 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 8 Apr 2026 15:00:32 -0700 Subject: [PATCH 2/6] Update src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Hosting/ConfigurationManagerConfigExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs index 5a5ecfdac..86a77bc2f 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Reflection; using System.Web; -using System.Web.Compilation; using System.Web.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Memory; From 7e129b709d927681658e41fd03c3f6aaafa48231 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 8 Apr 2026 15:00:40 -0700 Subject: [PATCH 3/6] Update src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Hosting/ConfigurationManagerConfigExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs index 86a77bc2f..06c610fde 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs @@ -84,7 +84,7 @@ static bool IsIISExpress() } /// - /// Does a best effort to get the the name of the assembly that was launched. This matches ASP.NET Core and allows things like UserSecrets to work. + /// Does a best effort to get the name of the assembly that was launched. This matches ASP.NET Core and allows things like UserSecrets to work. /// private static string GetExecutingAssemblyName() { From 8c3b400dccb13ca487815136c7f968066957c4cd Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Fri, 10 Apr 2026 15:31:58 -0700 Subject: [PATCH 4/6] add comments --- .../ConfigurationManagerConfigExtensions.cs | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs index 06c610fde..cfe259752 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs @@ -53,7 +53,7 @@ public static IConfigurationManager UseHostingEnvironmentFallback(this IConfigur if (configuration[HostDefaults.ApplicationKey] is null) { optionList = new(); - optionList.Add(new KeyValuePair(HostDefaults.ApplicationKey, GetExecutingAssemblyName())); + optionList.Add(new KeyValuePair(HostDefaults.ApplicationKey, GetDefaultApplicationName())); } if (configuration[HostDefaults.EnvironmentKey] is null && (HostingEnvironment.IsDevelopmentEnvironment || IsIISExpress())) @@ -73,31 +73,45 @@ public static IConfigurationManager UseHostingEnvironmentFallback(this IConfigur configuration.AddInMemoryCollection(optionList); } - static bool IsIISExpress() + return configuration; + + /// + /// Does a best effort to get the name of the assembly that was launched by trying to find it via the active . + /// By using the name of the assembly, it matches ASP.NET Core behavior and allows things like UserSecrets to work which use that name to + /// identify where the secrets are. + /// + static string GetDefaultApplicationName() { - using var currentProcess = Process.GetCurrentProcess(); + // When called in HttpApplication.Application_Start, there is an initial HttpContext.Current that is set even though we're not in an actual request + if (HttpContext.Current is { ApplicationInstance: { } app }) + { + var type = app.GetType(); - return string.Equals(currentProcess.ProcessName, "iisexpress", StringComparison.Ordinal); - } + // The ApplicationInstance is generally a derived one generated by ASP.NET, so we need to check base types until we find the real one. + // The generated ones are marked with the GeneratedCodeAttribute, so we can check for that and skip them. + while (type.Assembly.GetCustomAttribute() is { } && type.BaseType.GetType() != typeof(HttpApplication)) + { + type = type.BaseType; + } - return configuration; - } + var name = type.Assembly.GetName().Name; - /// - /// Does a best effort to get the name of the assembly that was launched. This matches ASP.NET Core and allows things like UserSecrets to work. - /// - private static string GetExecutingAssemblyName() - { - // This is available in the startup even though we don't have a current request - var type = HttpContext.Current.ApplicationInstance.GetType(); + if (type != typeof(HttpApplication) && !string.IsNullOrEmpty(name)) + { + return name; + } + } - // The ApplicationInstance may be a custom one generated by ASP.NET, so we need to walk up until we find the real one. - // The generated ones are marked with the GeneratedCodeAttribute, so we can check for that. - while (type.Assembly.GetCustomAttribute() is { } && type.BaseType.GetType() != typeof(HttpApplication)) - { - type = type.BaseType; + // Fall back in case HttpContext.Current is not available; most likely this will be the case in the test environment where the HttpApplication + // is not starting up + return HostingEnvironment.SiteName ?? AppDomain.CurrentDomain.FriendlyName; } - return type.Assembly.GetName().Name; + static bool IsIISExpress() + { + using var currentProcess = Process.GetCurrentProcess(); + + return string.Equals(currentProcess.ProcessName, "iisexpress", StringComparison.Ordinal); + } } } From 63a6205a9ea215fcc8465815664f2f1bbfb2c448 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Fri, 10 Apr 2026 15:33:04 -0700 Subject: [PATCH 5/6] use simplified new commands --- .../Hosting/ConfigurationManagerConfigExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs index cfe259752..0634d9c6a 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs @@ -53,19 +53,19 @@ public static IConfigurationManager UseHostingEnvironmentFallback(this IConfigur if (configuration[HostDefaults.ApplicationKey] is null) { optionList = new(); - optionList.Add(new KeyValuePair(HostDefaults.ApplicationKey, GetDefaultApplicationName())); + optionList.Add(new(HostDefaults.ApplicationKey, GetDefaultApplicationName())); } if (configuration[HostDefaults.EnvironmentKey] is null && (HostingEnvironment.IsDevelopmentEnvironment || IsIISExpress())) { optionList ??= new(); - optionList.Add(new KeyValuePair(HostDefaults.EnvironmentKey, Environments.Development)); + optionList.Add(new(HostDefaults.EnvironmentKey, Environments.Development)); } if (configuration[HostDefaults.ContentRootKey] is null) { optionList ??= new(); - optionList.Add(new KeyValuePair(HostDefaults.ContentRootKey, HostingEnvironment.ApplicationPhysicalPath)); + optionList.Add(new(HostDefaults.ContentRootKey, HostingEnvironment.ApplicationPhysicalPath)); } if (optionList is not null) From 0be9ed93630cc6d0caca02dece03489036536a27 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Fri, 10 Apr 2026 15:33:24 -0700 Subject: [PATCH 6/6] nit spelling --- .../Hosting/ConfigurationManagerConfigExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs index 0634d9c6a..c78b87094 100644 --- a/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs +++ b/src/Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices/Hosting/ConfigurationManagerConfigExtensions.cs @@ -102,7 +102,7 @@ static string GetDefaultApplicationName() } } - // Fall back in case HttpContext.Current is not available; most likely this will be the case in the test environment where the HttpApplication + // Fallback in case HttpContext.Current is not available; most likely this will be the case in the test environment where the HttpApplication // is not starting up return HostingEnvironment.SiteName ?? AppDomain.CurrentDomain.FriendlyName; }