Closed yaakov-h closed 1 year ago
@twsouthwick we add all environment variables to configuration by default.
Perhaps for application configuration, but fir host config only dotnet and aspnetcore according to https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-7.0#host-configuration
Since one use case is to use the app pool name to load appsettings.{apppoolname}.json for the application, it would be useful to be able to use the host configuration rather than system.environment to manually grab them.
I see, it’s reosnable to make them ASPNETCORE prefixed then
@twsouthwick
@yaakov-h you've had https://github.com/dotnet/aspnetcore/issues/43632#issuecomment-1656640252 with environment variables like this. Can you expound on that?
I've had issues particularly with MSBuild, which used environment variables in a similar manner. Specifically:
I don't see the same situation happening here as easily, but it still could happen - if an IIS-hosted ASP.NET Core app launches a child or grandchild ASP.NET Core app, that child process could think it is being hosted in IIS but the settings it is seeing is that of the parent process and not its own.
@yaakov-h I believe we went over these scenarios in the API review and we should include them in any documentation to be aware of.
@twsouthwick yeah, I noticed it in the API review notes above and tried to see if there was more detail somewhere, but this API review doesn't seem to have been YouTubed. 🙃
As long as it's something that's solvable, then it should be fine. FWIW in the MSBuild case I had to move all of my project evaluation API calls to a subprocess, but here you can't exactly move "be hosted in IIS" to a subprocess.
For those wanting to try it out, rc2 has the feature, and installing the rc2 hosting bundle will enable it in IIS. However, IIS Express is managed by VS and will require an update to the ANCM it ships to enable the feature from being inserted as expected. I'll update here when that's available
Moved from #43631.
Background and Motivation
When an ASP.NET Core application is hosted in IIS, IIS gives it an application ID, the same way it gives every other application an application ID. This contains the site ID (numeric) and virtual directory path, and is already used in ASP.NET Core to initialize ANCM and I believe to determine the value of
HttpRequest.PathBase
.The particular scenario I have at the moment is a web application that runs multiple instances on different domains from the same physical path on disk. The only way the application can differentiate between instances e.g. for additional config or cache directories) is the IIS site ID.
In .NET Framework / ASP.NET applications, this value is available via
HttpRuntime.AppDomainAppId
which reads it from the current AppDomain's data. In ASP.NET Core, this value is currently only available during the lifetime of a request viaIServerVariablesFeature
, but outside of a single request there is no API for it.I believe that applications that are hosted in IIS and rely on this value outside of a request lifetime (e.g. during startup or during background work) should be able to be ported from ASP.NET / .NET Framework to ASP.NET Core on modern .NET without needing to completely rework any logic that uses the AppDomainAppId.
The value is, however, already known internally to the ASP.NET Core Module and can be reached via reflection and pointer arithmetic. Making it available to the rest of the application is a question of "how", not "if".
Proposed API
This API will depend upon the following additional behavioural changes, though they are not direct changes to the public API surface:
WebHostBuilderIISExtensions.UseIIS
will set this key viaIWebHostBuilder.UseSetting
.Microsoft.AspNetCore.Server.IIS.Core.IISConfigurationData
will get a newstring
field to transfer this value from the native IIS module to the managed ASP.NET Core runtime.http_get_application_properties
will copy the config path from unmanaged code into the struct to be marshalled back to managed code.Usage Examples
Alternative Designs
I did consider a method similar to .NET Framework of exposing a static function/property, as
http_get_application_properties
can be called from anywhere, however this does not easily allow the consuming code to be tested or for stub/mock values to be provided. Every consumer that wished to do so would immediately create their own interface and implementation to simply wrap this static call.Risks
This will require changes to ANCM, and I do not know what the forwards-compatibility and backwards-compatibility concerns here are and how to mitigate them.
Looking at the most recent change which added a field to the IISConfigurationData struct, there appear to be no compatibility mitigations / versioning / traditional
dwSize
fields etc., so this may not be a concern?Additional Notes
This can be done already, albeit extremely hackily, by reflection and pointer arithmetic to access values stored within the IIS integration memory:
I would much rather this be exposed as an API as this relies heavily on not just ASP.NET internals but also the memory layout of underlying native types.
I am happy to drive the implementation myself with a PR, once a design is approved.