Closed Tratcher closed 8 years ago
Should handle that based on the path passed into server.urls
Yes, but how do you get that information from IIS to server.urls? Right now we only get the port.
We'd need to restructure a bit. It can be setup in the M.A.Hosting.json file.
Workaround: put your app in a app.Map("/vdir" ... https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552
Please don't require us to hard code the IIS vdir in external config files, like M.A.Hosting.json, when IIS and HttpPlatformHandler already know this.
Just pass this information on for example in an environment variable, like %HTTP_PLATFORM_VDIR%, so you can say
<httpPlatform stdoutLogEnabled="false" stdoutLogFile="log.log" startupTimeLimit="20" processPath="%HOME%\site\kestrel.cmd" arguments="http://localhost:%HTTP_PLATFORM_PORT%/%HTTP_PLATFORM_VDIR%">
<environmentVariables></environmentVariables>
</httpPlatform>
@rubenprins That fix is coming. This is a workaround until the fix is available. We're working with the httpPlatformHandler team to fix bugs found in beta8 and rc1.
I don't understand the workaround.
Are you saying we need to configure the sub-application within the parent application. Essentially copying the Configure method of the sub-application into the parent?
Sup-apps have different paths (e.g. /subapp/controller/foo) which breaks routing. The workaround is to use Map("/subapp"... In your sub app to remove the extra path segment.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.Map("/testvirt", map => Configure1(map, env, loggerFactory));
}
// Configure is called after ConfigureServices is called.
public void Configure1(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.MinimumLevel = LogLevel.Information;
loggerFactory.AddConsole();
loggerFactory.AddDebug();
// Add the platform handler to the request pipeline.
app.UseIISPlatformHandler();
app.UseDefaultFiles();
// Configure the HTTP request pipeline.
app.UseStaticFiles();
}
I havent been able to get the workaround to work with an app configuration above.
Updated workaround with the latest RC2 packages (https://github.com/aspnet/IISIntegration/issues/52#issuecomment-171444840).
The next version of HttpPlatformHandler (1.3?) will provide the base path via HTTP_PLATFORM_APPL_PATH and UseIISPlatformHandlerUrl will apply it. Until that version is released you can add HTTP_PLATFORM_APPL_PATH to the environment variables section of the httpPlatform web.config with a value like /MySubApplication
.
@Tratcher :beers:
All y'all winning at life and such
I also got my stuff working with a little help from @davidfowl
Until that version is released you can add HTTP_PLATFORM_APPL_PATH to the environment variables section of the httpPlatform web.config with a value like /MySubApplication.
Just to clarify here - does this workaround function on its own, like this:
<httpPlatform processPath="..\approot\web.cmd" arguments="" stdoutLogEnabled="false" stdoutLogFile="..\logs\stdout.log" startupTimeLimit="3600">
<environmentVariables>
<environmentVariable name="HTTP_PLATFORM_APPL_PATH" value="testbed" />
</environmentVariables>
</httpPlatform>
or does it need to be done in tandem with the Configure
changes mentioned previously?
Also, is this expected to work in HTTP Platform Handler 1.2, or do we need some kind of nightly/RC?
[Because as it stands, I've had no luck with just the web.config change and HTTP handler 1.2]
That should be value="/testbed"
, and yes it should work with HttpPlatformHandler 1.2 and our latest RC2 packages. This should replace the Map workaround.
Thanks for together providing a visible, valid example, @DavidR91 and @Tratcher
I tried adding the environmentVariables element to web.config source file, but dnu publish removes it when inserting DNX_PATH and DNX_ARGS. I tried with dnu rc2-16357. I guess this requires a post-publish modification.
this is what we refer to as a FON! a F#^%$#K UP OF NOTE! Have tried every single one of the fixes mentioned here and elsewhere ...6 hours & still no end in sight! Have no idea what the heck you blokes are doing that side but its not working for the rest of us plebs!
There seems to be a lot of confusion about this feature, so I suggest we get some troubleshooting tips on how to see what's going on behind the scenes. My situation:
While inspecting the application log files (I've configured the httpPlatform
element with stdoutLogEnabled
set to true
), I see that the requests go to /virtual
directory where the app should be deployed, but the app itself can't handle this. I also see that the web.config
looses the environment settings (environmentVariables
element) when "publishing the application to file system" (that's probably unrelated issue).
So, neither the solution with the web.config
nor the app.Map()
works (in my case) for a simple scenario of deploying the new ASP.NET MVC 6 app under the virtual directory. Time permitting, I'll test with an almost empty ASP.NET 5 app.
What is also very puzzling is that IIS is not serving the static files, but kestrel is.
Questions:
This is causing me one hell of a headache! Is there any workaround with Asp.Net Core RC1 and HttpPlatformHandler 1.2, or nothing until the next releases?
@dotcom9:
With RC1 all you should need to do is wrap the contents of Startup.Configure
with app.Map("/virtual-path-name", ...)
.
@skyflyer:
www.example.com
and your virtual application is named my-virtual-app
, you will deploy to www.example.com\my-virtual-app
. App nesting is, once again, no different. And once RC2 and the update for HttpPlatformHandler are officially released, you should just be able to use it without thinking about it, just like before.@tuespetre,
@skyflyer:
Pretty much, which is a good thing IMO.
I have been successfully deploying RC1 apps to separate virtual directories. Just haven't had the time to share the setup and was thinking that it all would change with RC2. But since it has not come out yet, i will try share here.
the script looks like this:
# bootstrap DNVM into this session.
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}
# load up the global.json so we can find the DNX version
$globalJson = Get-Content -Path $PSScriptRoot\..\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore
if($globalJson)
{
$dnxVersion = $globalJson.sdk.version
}
else
{
Write-Warning "Unable to locate global.json to determine using 'latest'"
$dnxVersion = "latest"
}
# install DNX
# only installs the default (x86, clr) runtime of the framework.
# If you need additional architectures or runtimes you should add additional calls
# ex: & $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -r coreclr
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent
# run DNU restore on all project.json files in the src folder including 2>1 to redirect stderr to stdout for badly behaved tools
Get-ChildItem -Path $PSScriptRoot\.. -Filter project.json -Recurse | ForEach-Object { & dnu restore $_.FullName 2>1 }
(Notice that i placed it in a build dir in my respository and it should look for project.json in the parent folder).
where the arguments for msbuild are
/p:TypeScriptCompileBlocked=true /t:Build,FileSystemPublish /p:PublishConfiguration=$(BuildConfiguration) /p:PublishOutputPathNoTrailingSlash=$(Build.SourcesDirectory)\artifacts\$(BuildConfiguration)\Publish
the TypescriptCompile is optional for this and something we build with grunt instead of vs. In VS2015 this is similar to publish to file system.
$(Build.SourcesDirectory)\artifacts\$(BuildConfiguration)\Publish\wwwroot\web.config $(Build.SourcesDirectory)\artifacts\$(BuildConfiguration)\Publish\web.config
You can do this after publish to file system manual if you dont use a build system. The reason for moving it to the parent is that we want each virtual app to site side by side.
/app1
/app2
/app3
and in each app you want
/app1/wwwroot
/app1/approot
/app1/web.config
One could also take a look at this SO Q/A : http://stackoverflow.com/questions/34784391/deploying-aspnet5-apps-to-virtual-directories-on-azure-websites where i wrote about it when i first ran into the problem.
Again I am using a build system.
What is needed to be done is that the httpPlatformPath needs to be updated.
I am doing this here: https://gist.github.com/s093294/e97de232ee6d9c563c8b#file-azurewebappdeploymenttask-cs-L189
and from the input parameters you may see that this is set to .\approot\web.cmd
(remember the folder structure above).
Setting the Environment variable (which my build task also do) ends up with a web.config that looks like this:
<configuration>
<system.webServer>
<handlers>
<remove name="httpplatformhandler" />
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath=".\approot\web.cmd" arguments="" stdoutLogEnabled="true" stdoutLogFile="%home%\LogFiles\stdout.log" startupTimeLimit="3600">
<environmentVariables>
<environmentVariable name="VIRTUAL_PATH" value="/pr/ascend-ammo-wildlife/47" />
</environmentVariables>
</httpPlatform>
</system.webServer>
</configuration>
where the VIRTUAL_PATH has to match the IISDir, where mine can be verified to match the azure website settings:
With the following startup class it works locally and deployed:
public class Startup
{
public Startup(IHostingEnvironment env)
{
}
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure2(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.MinimumLevel = LogLevel.Information;
loggerFactory.AddConsole();
loggerFactory.AddDebug();
app.UseIISPlatformHandler();
app.UseFileServer(true);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("VIRTUAL_PATH")))
app.Map(Environment.GetEnvironmentVariable("VIRTUAL_PATH"), (myAppPath) => this.Configure2(myAppPath, env,loggerFactory));
else
Configure2(app, env, loggerFactory);
}
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
Since I have all this configured in Visual Studio Team Services and could package it as an extension. If you feel that this is valuable if you could click and install the steps and make VSTS deploy it for you in the same setup as above. Feel free to send me a email at pks@s-innovations.net. I have been thinking about how to distribute it and would like to ask a few questions. (Also remember that VSTS is free up to 5 users, so even if you dont use it - it is easy to start using it).
@tuespetre thanks
This as been fixed in AspNetCoreModule v0.8: https://github.com/aspnet/IISIntegration/issues/105.
Asp.net core still not working under virtual directory in IIS
@leo9223 virtual directories or sub applications? These are commonly confused. Sub applications should work but there's no support for virtual directories.
@Tratcher Virtual directories are not working, but when I convert that directory to application then it is working. yea sub application is working.
@Tratcher However different webconfigs working for IIS10 and IIS8.5
on IIS10 app works with this setting
<aspNetCore processPath="dotnet" arguments=".\myApp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
on IIS8.5 app works with this setting
<aspNetCore processPath="C:\Program Files\dotnet\dotnet.exe" arguments=".\myApp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
I don't know why. can you please tell me why it is happening?
Your IIS 10 machine probably has dotnet on the system path, where your other machine doesn't. Did you restart the second machine after the install?
@Tratcher I just restarted the IIS not the machine, let me check. Thank you
@leo9223 Just for future reference, @pan-wang advised for the docs that you should be able to avoid a restart if you execute net stop was /y
followed by net start w3svc
.
I have the same problem.. I want to add ASP.NET Web API application (Admin) under ASP.NET Core website (Test) as shown in the image below. But the admin doesn't work because of the corehandler. How do I ask the corehandler to just work with the root application but not the applications inside it.
@buddalasunil999 Web.Config files are inherited by child apps. inside your admin web.config in the handlers section you can remove the aspNetCore handler that was added in the parent site.
@Tratcher Yeah just figured it out.. it's inherting the handler, added remove handler to child config and started working. Thanks
@Tratcher you say "there's no support for virtual directories.". After I saw this comment I have searched everywhere to have it confirmed without finding anything on it, except in comments from you.
Are you saying I will have to set up a new site and deploy there?
So the setup below will never work because posservice is a virtual directory?
What I need is to be able to call this web api url ? https://A.HTTPS.Site/posservice/api/v1/authentication/accesstoken
My api controller attribute routing looks like [Route("api/v1/authentication")]
with this on a method [HttpPost("accesstoken"), AllowAnonymous]
I have tried just about everything under the sun I believe (even some map https://github.com/aspnet/IISIntegration/issues/14#issuecomment-150716529 things).. so some help would be appreciated :-)
Yes, if you made the posservice level a sub-application and pointed it at your ASP.NET Core app then it should work. Also remove the nested posservice/api and /posservice/api/v1 sub-applications definitions, they'll mess up your routing. Any segments marked as a sub-application get moved from HttpContext.Path to HttpContext.PathBase and Rout only operates on Path.
Hi,
previously on full .net there was System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath
which returned virtual dir/app name.
Having HttpContext.PathBase
is very nice, but it exists only during request handling, which ApplicationVirtualPath
was available in IHttpModule.Init
for example.
Is there any way to get base path before on starup/configure (before request processing)?
@evil-shrike why do you need it?
@davidfowl I'm migrating some app/lib onto core from mvc5 and there I have some global singleton config (let's call it XConfig) which is available via DI for other components. I put the base path from ApplicationVirtualPath into that XConfig on start. Then for example some View calls its Model's method, which returns some html markup, for this it uses other injected component which only has XConfig and takes basePath from it. Now I have to pass HttpRequest all the way (better), on initialize XConfig on first request (worse). I'm not telling that it will be impossible or bad but just decided to ask. As probably server (IIS) can pass this info on initializing not only on request handling.
Hi when i deploy asp.net core 2.0 with IIS Windows authentication I am getting Cors Error with angular. Please suggest any example
When we're spun up behind IIS / HttpPlatformHandler how do we know what the virtual directory is? We need this to correctly set PathBase in the app. Ideally we'd set PathBase as part of the initial server address configuration, but at that point we're only given the port via environment variable. @davidfowl