Hooking up sub applications in ASP.NET Core - c#

I have two projects in asp.net core 2.1. One is the main web application, and the other is a sub-application. The sub-application is for the most part, independent; it only needs cookies from the main application.
I'm trying and failing to set up the two projects in my local dev environment, and I will also need to set up for live IIS Deployment in the future. I have both VS projects in the same VS Solution. In their project Debug settings page, I have them both set up to launch IISExpress with app URL as 'http://localhost:44305'. I have tried setting the subapp to 'http://localhost:44305/subapp' too, but when vs run, IISExpress complains that the port is already in use.
I have a web config for both apps. The very basic defaults for both. In the sub app, I have the extra line to remove the aspnetcore handler (as I found from searching).
<remove name="aspNetCore" />
In the sub app, i have also tried adding in startup.cs:
app.UsePathBase("/subapp")
The results I get from this setup running in vs locally is that on the base URL, it actually loads up my subapp instead of my main app (browser URL is localhost:44305). Fiddling with multiple settings seems to get me nowhere; either both apps fail to load completely, or one or the other app is inaccessible.
Is there any proper documentation out there for setting up multiple apps to work together locally and in IIS? Everything I seem to find is from pre-2.0.
Thank you for your help!
Edit:
I actually managed to get a fresh project working as subapp when deploying to IIS. To set up:
Make a new VS solution with two aspnetcore 2.1 web applications.
Add a web.config to sub application with following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
</handlers>
<aspNetCore processPath="dotnet" arguments=".\IISTestSubApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
No web config for Main app.
Add .UseIISIntegration() to Program.cs CreateWebHostBuilder to both apps.
In Startup.cs Configure method for Subapp, add app.UsePathBase("/subapp/");
Deploy main app to a folder /Mainapp. Deploy sub app to /Mainapp/subapp.
Set up iis website for main app.
Right click on main app website in IIS and click Add Application. Add the subapplication with an alias '/Subapp'
That should be all you need. Some of the steps may not be necessary. I haven't fully tested which steps are 100% necessary.
Unfortunately, I still can't get it to work with IISExpress. I have my .vs/applicationhost.config file looks almost exactly like the IIS one, but when running both apps at the same time, i get errors saying that the port is already in use. I'm still trying a bunch of new things, so, we'll see if I can figure it out.

I got it working now in IISExpress. Following the above steps for IIS first, for basic setup, include the following:
The subapp web.config file should look like this for IISExpress:
<configuration>
<system.webServer>
<handlers>
</handlers>
<aspNetCore processPath="dotnet" arguments=".\bin\Debug\netcoreapp2.1\IISTestSubApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
In your solution's .vs/config/applicationhost.config file, make sure your sites section looks like
<site name="IISTest" id="2" serverAutoStart="true">
<application path="/" applicationPool="IISTest AppPool">
<virtualDirectory path="/" physicalPath="C:\Users\user\Documents\GitHub\IISTest\IISTest" />
</application>
<application path="/subapp" applicationPool="IISTest AppPool">
<virtualDirectory path="/" physicalPath="C:\Users\user\Documents\GitHub\IISTest\IISTestSubApp" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:44301:localhost" />
</bindings>
</site>
It seems okay that both apps use a different application pool. Setting them the same gets overwritten when vs runs, for some reason.
Run only the main app from vs; Don't try to run sub apps as well. You will get port already taken error message.

Related

Why is web.config getting created on publish not on build the project in Asp.Net Core API?

I have Asp.net Core 3.1 API project. When I build it doesn't create any web.config file, but when I publish the API using VS 2019 in a folder, it creates a web.config file.
So why it's not creating web.config on build ( I think it should not create because there is no web.config file in the project) but why does it create web.config file on publishing?
Edit: I am trying to deploy the application through Octopus, So I copy the bin folder content, and I need the web.config also. So for time being, I have manually created the web.config in the project and then building the project. so it copies the web.config to the bin folder. So Is this the right approach? or is there any way to generate web.config in the bin folder without manually creating it?
As far as I know, the web.config is used to tell IIS about how to use asp.net core module and handler to host the asp.net core application. When you build and test the application in the VS, there is no need to create the web.config, since it will read the launchSettings.json not web.config.
Web.config is a server configuration file, it is used to configures the ASP.NET Core Module.
The web.config file may provide additional IIS configuration settings that control active IIS modules. For information on IIS modules that are capable of processing requests with ASP.NET Core apps, see the IIS modules topic.
Asp.net core web.config content(Without this file, we couldn't directly host the asp.net core application on IIS)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\basket.api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
</aspNetCore>
</system.webServer>
</location>
</configuration>
IIS requires a web.config file for apps that run there.
In ASP.NET Core, web.config is lazy-generated. The assumption (flawed, IMO) is that you don't need web.config until you are ready to publish to IIS. But what if you have your IIS app pointed to your local code instance so that you don't have to republish your app every time you make a code change and want to test it in IIS? Or what if, like OP, you want to use alternate deployment methods?
A workaround in that case is to publish your app once, take the generated web.config, and copy it to the root of your VS project (same level as the bin folder). Subsequent builds will then copy the web.config to bin\debug\net6.0. Still not ideal, but this is better than manually creating web.config and potentially introducing an error in the file.

.net core application error 502.5 if run as virtual directory in IIS

I am having problem configuring .net core application to work as virtual directory in iis.
If i start .net core application directly with its port it works fine.
I am getting 502.5 response and in event viewer there is this message
Application 'MACHINE/WEBROOT/APPHOST/DEFAULT WEB SITE' with physical root 'C:\inetpub\wwwroot\' failed to start process with commandline ' ', ErrorCode = '0x80070057 : 0.
I have removed parent handlers in .net web.config like this
<handlers>
<remove name="httpPlatformHandler"/>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
</handlers>
In order to run an ASP.NET Core application make sure you:
Have the ASP.NET Core Web Hosting Bundle (required for a server!)
Publish your application - should include a web.config
Deploy the Publish output to your server
Set up an Application Pool
Set .NET Framework to none (optional but usually a good idea)
Use an account that has read permissions in the virtual folder
The hosting bundle includes the ASP.NET Core Module for IIS which allows IIS to launch. Without ASP.NET Core apps will not run on IIS.
You also need to publish your application, which produces a final output folder that contains your binaries and config files including a web.config in the root and a wwwroot root folder with your content. To test you should make sure you can run your app from the command line with:
dotnet yourMainAssembly.dll -c Release
If this doesn't work fix this first as this is essentially what IIS fires. once the standalone works you can try using IIS.
ASP.NET Core projects created in Visual Studio automatically include a web.config and that should have everything you need to run under IIS. For a basic setup that should be all you need. The generated web.config should take care of getting your app running.
If you're using a virtual you might have an issue with the parent side configuration bleeding into your virtual because virtuals inherit settings from the parent. If that's the case either choose the same version of .NET Framework for your application pool, or share the application pool with the parent. Alternately you can use <clear /> in the <handlers> section to clear out any handlers from up the hierarchy.
<configuration>
<system.webServer>
<handlers>
<clear>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00">
<environmentVariables />
</aspNetCore>
</system.webServer>
</configuration>
I have a blog post with a lot more details on hosting on IIS along with some additional configuration for static files here:
Publishing and Running ASP.NET Core Apps under IIS
IIS Rewrite Rules and Static File Configuration for ASP.NET Core

ASP.NET Core IIS Project not running or producing any logs

I have:
an EC2 instance running Windows Server 2016,
the .NET Web Host Bundle installed (including the .NET Core 2 SDK),
the AspNetCoreModule installed,
a site in IIS10 and an app pool with no managed code,
the following BuildWebHost:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
this web.config for ASP.NET Core 2 MVC in the sites root folder:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\ProjectOutput.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
</system.webServer>
</configuration>
What works:
placing an index.html with any content in the root folder of the site.
the content of the file is served properly when I goto the site from an external network or computer.
What doesn't work:
placing my published ASP.NET Core MVC site in the root folder of the site, serves a 500 Internal Server Error
published using dotnet publish
additionally, nothing is getting logged either.
What could I be missing that would cause my project to not start, without any logging?
I know I commented an houre ago, but reading this issue I thought I had the same problem.
What helped for me was removing the following from the Startup.cs in the configureServices method:
Services.AddDeveloperSigningCredential();
I noticed that when publishing the application, the application in IIS was still asking for a tempkey.rsa. That's weird because this one is not published with it. So after removing the certain line of code it's all working.
Also a great tip to remember, if you can't figure out the error: go to the folder of your application. Open command. And enter: dotnet .\NAMEOFSTARTING.DLL
This way you start your website from the command, and see possible errors.

How to fix HTTP Error 500.22 - Internal Server Error An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode

I'm learnig about Http modules and during last try I received:
HTTP Error 500.22 - Internal Server Error An ASP.NET setting has been
detected that does not apply in Integrated managed pipeline mode.
One of the suggested solution is:
from the IIS Express install directory, run appcmd migrate config "Default Web Site/".
So from Command prompt I went to C\Program Files\IIS Express and then I executed: appcmd migrate config "Default Web Site/"
I received command "Migrate" is not supported on object config.
How to do it properly?
Chk my SO Post
Finally, I'm able to crack it for VS.Net 2015 and its configuration of IISExpress. ITs not possible to configure it 'externally' and nothing will work if you keep modifying IIS or IISExpress settings outside VS.Net.
It took me a while to narrow down my focus to VS.Net proj properties and configurations. I found that VS.Net created its own version of "applicationhost.config" which can be found at -
<myProject.sln path> \.vs\config\applicationhost.config
This is the file in which I had to change the application pool (applicationPool="Clr4ClassicAppPool) -
<sites>
<site name="WebSite1" ... ignore this sction if present
</site>
<site name="myProject" id="2">
<application path="/" applicationPool="Clr4ClassicAppPool">
<virtualDirectory path="/" physicalPath="D:\Source\myProject" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:1960:localhost" />
</bindings>
</site>
You just need to change the applicationPool (your Classic App pool name might be diff in that case get the correct one from in the same file). Also make sure you're updating the correct "site" node (the correct localhost url of your web app when debugged from VS.Net)
If still there's an issue set the following -
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
Hope this helps.
you should change your web.config with the following:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>

How to get IIS to recognize OWIN startup class?

My OWIN web service runs beautifully in Visual Studio 2013, but when I publish it to a real IIS site, it acts as if the Configuration method in the startup class has not been run. I can do "normal" things like browse to the app and see the directory structure, but nothing that was supposedly set up with the IAppBuilder is functional. For example, I get a 404.0 error when I browse to a URL that was set up in Startup to issue an OAuth2 bearer token. It's as if Startup.Configuration(IAppBuilder app) was never run.
I'm using the [assembly: OwinStartup(typeof(MyNamespacedStartupClass))] attribute to designate the startup class.
I've used NuGet to get both Microsoft.Owin.Host.SystemWeb and Microsoft.Owin.Diagnostics per instructions I've seen, but that doesn't make a difference.
What more do I have to do?
Make sure your app pool is in v4.0 integrated mode.
Make sure you have bin placed Microsoft.Owin.Host.SystemWeb (I see you have installed it) - Just make sure its also in the bin folder.
This article will have more information on how an OWIN middleware runs on Integrated pipeline.
I also had to add an extra setting to my web.config
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
From: https://katanaproject.codeplex.com/wikipage?title=Static%20Files%20on%20IIS
IIS has a native static file module that is optimize to skip other
portions of the pipeline if it sees file paths that do not match other
handlers (e.g. not aspx). This means that the directory browser
middleware is likely to work, but then the static file middleware may
be bypassed in favor of the native static file module.
This tells IIS not to skip the managed Asp.Net modules even if the
native static file module thinks it has a match.
It also describes another step, but this was not needed for me:
Also, add the following stage marker AFTER your static file middleware
(in namespace Microsoft.Owin.Extensions):
app.UseStageMarker(PipelineStage.MapHandler);
Probably the reason if you upgraded at some point from an older MVC:
Make sure you don't have
<add key="owin:AutomaticAppStartup" value="false" />
in your web.config. It will suppress calling the startup
Instead change it to this
<add key="owin:AutomaticAppStartup" value="true" />
Somewhere along the line - when I upgraded to MVC 5 this got added (actually almost ironically it was a year ago tomorrow) and I never even knew what owin was until today when I tried to use it.
I also faced same problems when I migrated my already running MVC5 site to a new server. It gave me nightmares, just to recap I had to do all this to get it working
Add [assembly: OwinStartupAttribute(typeof([YourAssemblyName].Startup))] this to the Startup class (after the using statements and before the namespace declaration)
Add these keys to the <appSettings> section of web.config
<add key="owin:AppStartup" value="[NamespaceForYourStartUpClass].Startup, [YourAssemblyName]" />
<add key="owin:AutomaticAppStartup" value="true" />
And lastly as suggested by Martijn Evens add the following to <system.webserver> section in web.config
<modules runAllManagedModulesForAllRequests="true" />
For those who deal with legacy and (or) have migrated versions. Check windows "Roles and features", find what version of ASP.net is installed, and use exactly the same version in web.config for targetFramework, for example in my case it was 4.6 not 4.8, so
<system.web>
<httpRuntime targetFramework="4.6" requestValidationMode="2.0" maxQueryStringLength="2097151" />
<compilation targetFramework="4.6" optimizeCompilations="true">

Categories