17

I know that is located in HttpContext.Request.PathBase, however I need it to configure my cookie before I have any HttpContext (in Startup.cs).

My problem:

When devops configure application they have to set path twice. Once in IIS application (so hosting knows what should be served) and in my appsettings.json (so application knows where to set cookies - multiple instances can work on server). I would like to configure it once in IIS, and have config passed to my application.

3
  • Where (when) in Startup? Commented Feb 26, 2018 at 14:52
  • @HenkHolterman Can be even after startup with IConfigureOptions. Configure or ConfigureServices are also ok. Commented Feb 26, 2018 at 17:00
  • 1
    stackoverflow.com/questions/42205577/… Commented Sep 23, 2018 at 7:25

6 Answers 6

8

There is a little confustion here that should be clarified.

You want to know application virtual path at application startup. However application virtual path is a concept of the hosting and specific request rather than underlying application. Hosting service uses this virtual path to map incoming url to application root. In IIS you can map multiple virtual paths to the same physical directory, e.g. /myApp1 and /myApp2 will point to the same application. Which of these paths do you want to get at application startup?

That's actually the reason why IHostingEnvironment interface does not provide any property for getting application virtual path. Another thing when application processes the request. In this case specific URL is requested and ASP.NET could provide requested virtual path in HttpContext.Request.PathBase.

You should reconsider your use case and check whether you actually need application virtual path for cookie configuration. It could be the XY problem. If you still have doubts regarding cookie configuration, please formulate it as a new question with specific details for your scenario.

Sign up to request clarification or add additional context in comments.

3 Comments

/myApp1 and /myApp2 will point to the same application - no, it will be two separate copies of application with shared contentRoot, configs etc; each one should have correct PathBase.
Added problem description to question.
It is IWebHostEnvironment now.
6
+50

You can check the environment variable ASPNETCORE_APPL_PATH. This is the variable AspNetCoreModule provides so that PathBase can be set correctly. See https://github.com/aspnet/IISIntegration/blob/df88e322cc5e52db3dbce4060d5bc7db88edb8e4/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs#L19

4 Comments

But what if you are using raw Kestrel?
Kestrel no longer directly supports base paths.
UsePathBase is still a thing, no?
This Environment Variable is only present if you are using the OutOfProcess hosting model. If you are using InProcess the information is only present on the HttpRequest.PathBase property.
3

I came across this question when looking for the answer myself and none of the current answers work for me (the use of environment variable ASPNETCORE_APPL_PATH looked promising but that also failed.)

My solution ugly but works:

    public static string? GetIISVirtualPath(this WebApplication app)
    {
        object iServer = app.Services.GetRequiredService<IServer>();
        PropertyInfo? pi = iServer.GetType().GetProperty("VirtualPath");
    
        return (pi?.GetValue(iServer) as string)?.ToLower();
    }

Rummaging about in the source the IServer implementation under IIS has an "VirtualPath" path property. So I grab that on startup.

Evil because MS can change this if they so desire, breaking this solution but I'll take that for now.

Comments

1

Starting in .NET 8, you can get this information from the public IIISEnvironmentFeature available on the IIS IServer implementation.

// Obtain the IServer implementation from the service provider.
// Can be obtained from HttpContext, dependency injection, etc.
IServer server = context.RequestServices.GetService<IServer>();
    
// Ask for the IIISEnvironmentFeature.
var iisEnv = server.Features.Get<IIISEnvironmentFeature>();
if (iisEnv != null)
{
    string appVirtualPath = iisEnv.ApplicationVirtualPath;
    // Other IIS properties can be accessed from this interface too.
}

The IIISEnvironmentFeature was introduced in .NET 8, but note that it can be null if the version of your installed ASP.NET Core IIS Module is significantly out of date.

Also note that ApplicationVirtualPath seems to always be uppercase, which could catch some migrating .NET Framework code by surprise. The only way I've found to get a correctly cased application virtual path is to extract it from the ApplicationId (another property on IISEnvironmentFeature).

Comments

0

Another extension similar to that @AnthonyWJones suggested:

    public static string? GetIISVirtualPath(this WebApplication app)
    {
        IServer iServer = app.Services.GetRequiredService<IServer>();
        return iServer.GetIISVirtualPath();
    }
    
    public static string? GetIISVirtualPath(this IServer server)
    {
        PropertyInfo? pi = server.GetType().GetProperty("VirtualPath");
        return (pi?.GetValue(server) as string)?.ToLower();
    }

The second one could also be handy with Dependency Injection.

Comments

-2

Just to add you can use @Url.Content("") in Javascript to get virtual directory base path.

<script src="@Url.Content("~/app/myapp.js")" type="text/javascript"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.