IIS applicationHost.config changes not reflecting - asp.net

I've created a test website to make use of the warm-up module provided by the Application Initialization Module.
I've used ScottGu's Blog as well as Wade Hilmo's Blog.
I've installed the module and implemented the changes to the applicationHost.config file and restarted the server:
<applicationPools>
<add name="MySite" autoStart="true" startMode="AlwaysRunning" managedRuntimeVersion="v4.0" />
</applicationPools>
<sites>
<site name="MySite" id="4" serverAutoStart="true">
<application path="/" applicationPool="MySite" preloadEnabled="true">
<virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot\MySite" />
</application>
</site>
</sites>
Once the server restarts, I check Task Manager and my site's not running. So then deleted the changes and used AppCmd to do it from the Command Prompt:
%windir%\System32\inetsrv\appcmd set apppool "MySite" /autoStart:true
%windir%\System32\inetsrv\appcmd set apppool "MySite" /startMode:AlwaysRunning
%windir%\System32\inetsrv\appcmd set app "MySite/" /preloadEnabled:true
%windir%\System32\inetsrv\appcmd stop apppool "MySite"
%windir%\System32\inetsrv\appcmd start apppool "MySite"
And Bobs your uncle it works perfectly. I then restarted the server for good measure and checked the applicationHost.config file again and the changes I've made are not there; yet the site is running fine in Task Manager and if I access the site it's available immediately. Stopping and starting the app pool sees the site immediately pop up in Task Manager.
So my question is, where are the settings being stored if not in the applicationHost.config file?!
Edit: I've done a lot of digging and playing but am no closer to an answer. Firstly, after some searching I found out there's another applicationHost.config file. The one I've been editing sits in
%windir%\System32\inetsrv\config\applicationHost.config
The second is apparently something to do with 32bit but the first applicationHost.config clearly shows the 32bit web sites. Even so, the second one didn't reflect my changes either
%windir%\SysWOW64\inetsrv\config\applicationHost.config
I did a search for applicationHost.config it found a few other copies of it but seems more like those are initial / backup copies of them.
I then created a second website, the two sites are now configured as such:
<applicationPools>
<add name="MySite" autoStart="true" startMode="AlwaysRunning" managedRuntimeVersion="v4.0" />
<add name="MySite2" autoStart="true" startMode="OnDemand" managedRuntimeVersion="v4.0" />
</applicationPools>
<sites>
<site name="MySite" id="1" serverAutoStart="true">
<application path="/" applicationPool="MySite" preloadEnabled="true">
<virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot\MySite" />
</application>
</site>
<site name="MySite2" id="2" serverAutoStart="true">
<application path="/" applicationPool="MySite" preloadEnabled="false">
<virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot\MySite" />
</application>
</site>
</sites>
First site should autostart and second site should be on demand.
I then ran the following AppCmd commands:
%windir%\System32\inetsrv\appcmd set apppool "MySite" /startMode:OnDemand
%windir%\System32\inetsrv\appcmd set app "MySite/" /preloadEnabled:false
%windir%\System32\inetsrv\appcmd set apppool "MySite2" /startMode:AlwaysRunning
%windir%\System32\inetsrv\appcmd set app "MySite2/" /preloadEnabled:true
to configure them the opposite way round to how they're configured in the applicationHost.config. I Restarted the server completely and checked the config, it's still as I originally left it and not reflecting the changes and neither site is starting.
I then changed the config of site 2 to autostart (as for site 1) and restarted the server but it still didn't start. I then ran:
%windir%\System32\inetsrv\appcmd set apppool "MySite2" /startMode:AlwaysRunning
%windir%\System32\inetsrv\appcmd set app "MySite2/" /preloadEnabled:true
%windir%\System32\inetsrv\appcmd stop apppool "MySite2"
%windir%\System32\inetsrv\appcmd start apppool "MySite2"
and it started, restarted server and it started up, though site 1 is still not starting on startup. So I ran:
%windir%\System32\inetsrv\appcmd set apppool "MySite" /startMode:AlwaysRunning
%windir%\System32\inetsrv\appcmd set app "MySite/" /preloadEnabled:true
and restarted the entire server again just for good measure and both sites are starting.

Are you using notepad++ to make these changes and to view the file? If so, use standard notepad that comes with Windows (or notepad2 if you've replaced notepad with notepad2). I guess notepad++ writes only to the 32 bit one by default (according to http://forums.iis.net/t/1151982.aspx?Opening+applicationHost+config+in+anything+other+than+Notepad).

Related

IIS 8.5 Configuration causes an issue with Sitefinity 12.1 dynamic link creation (ASP.NET .NET 4.7.2)

I'm running IIS 8.5 on Windows Server 2012 R2. It's a test server and I have 3 sites running on it, Dev, QA, and Staging.
The issue is with QA. The ASP.NET Sitefinity application running there resolves the incorrect domain name when it dynamically creates links. Specifically it uses the www in the domain instead of qa. So, https://qa.myexamplesite.com is the desired link, but it creates https://www.myexamplesite.com.
There is a www.myexamplesite.com but it is hosted on a completely different machine. Also, the application code does not contain references to the domain.
Dev and Staging are working fine. I changed the physical path of QA to point to Dev, but QA is still broken. I changed the physical path of Dev to point to the QA application code, but Dev does not break - still works fine. At this point, I'm reasonably sure that there is a configuration issue in IIS but I've so far been unable to find it. I've also been unable to recreate the issue on my local machine.
Here are the configuration details from the ApplicationHost file ommiting any sensitive or non-pertinent information:
<applicationPools>
<add name="DefaultAppPool" />
<add name=".NET v4.5 Classic" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" />
<add name=".NET v4.5" managedRuntimeVersion="v4.0" />
<add name="dev.myexamplesite.com" autoStart="true" />
<add name="staging.myexamplesite.com" autoStart="true" />
<add name="qa.myexamplesite.com" />
<applicationPoolDefaults managedRuntimeVersion="v4.0">
<processModel identityType="ApplicationPoolIdentity" />
</applicationPoolDefaults>
</applicationPools>
<sites>
<site name="dev.myexamplesite.com" id="1" serverAutoStart="true">
<application path="/" applicationPool="dev.myexamplesite.com">
<virtualDirectory path="/" physicalPath="S:\Dev\myexamplesite" />
<virtualDirectory path="/App_Data/Sitefinity/Search" physicalPath="S:\Dev\SitefinitySearch" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:80:dev.myexamplesite.com" />
<binding protocol="https" bindingInformation="*:443:dev.myexamplesite.com" sslFlags="0" />
</bindings>
</site>
<site name="staging.myexamplesite.com" id="3" serverAutoStart="true">
<application path="/" applicationPool="staging.myexamplesite.com">
<virtualDirectory path="/" physicalPath="S:\Staging\myexamplesite" />
<virtualDirectory path="/App_Data/Sitefinity/Search" physicalPath="S:\Staging\SitefinitySearch" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:80:staging.myexamplesite.com" />
<binding protocol="https" bindingInformation="*:443:staging.myexamplesite.com" sslFlags="0" />
</bindings>
</site>
<site name="qa.myexamplesite.com" id="2" serverAutoStart="true">
<application path="/" applicationPool="qa.myexamplesite.com">
<virtualDirectory path="/" physicalPath="S:\QA\myexamplesite" />
</application>
<bindings>
<binding protocol="https" bindingInformation="*:443:qa.myexamplesite.com" sslFlags="0" />
<binding protocol="http" bindingInformation="*:80:qa.myexamplesite.com" />
</bindings>
</site>
<siteDefaults>
<logFile logFormat="W3C" directory="%SystemDrive%\inetpub\logs\LogFiles" />
<traceFailedRequestsLogging directory="%SystemDrive%\inetpub\logs\FailedReqLogFiles" />
</siteDefaults>
<applicationDefaults applicationPool="DefaultAppPool" />
<virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>
I've been working through the resources to try to find where this problem could exist. The application is using Sitefinity propietary methods to dynamically create the links, so I've been unable to pin down exactly what method they are using. Here is some of the weird behavior I've been able to document.
I can refresh IIS, flushdns etc but the behavior does not change. I've restarted the server but the issue remains.
After a refresh, if I navigate to the site using a browser on the server then the URLs resolve correctly consistently. If I navigate to the site from an incognito browser then similarly the URLs are correct UNTIL I reload a few times, usually by the second or third page load the URLs are incorrect again. This is true regardless of the browser I'm using.
It seems like an IIS caching issue - but I can't track down where this is configured. There is no configured output caching that I can detect.
(aside) If it's helpful - the application code is calling this method from the open sourced Sitefinity library feather:
https://github.com/Sitefinity/feather/blob/master/Telerik.Sitefinity.Frontend/Mvc/Helpers/HyperLinkHelpers.cs
It's specifically calling GetFullPageUrl (line 149). However, I found this of limited use since it calls UrlPath which is a member of the proprietary Telerik.Sitefinity.Web.
I appreciate any insight, resources, direction, thoughts or rebukes on this problem.
Thanks
Can you go to Administration > Settings > Advanced > System > Site URL Settings
and see if Enable non-default Site URL Settings is checked and if the Host field is hard-coded to any of the other sites.
If so, you may want to correct it.
I want to partially credit Veselin Vasilev since he was on the right track. So here's what happened and how we fixed it.
At the time the error had started to occur we had another Sitefinity instance running and pointed to the QA db. Sitefinity, for some reason, started referring to a piece of db configuration after this event. It's not clear what this trigger was precisely, or what allowed it to work so long prior to that event with this incorrect information.
The db configuration in question is a table called sf_sites. There is an entry called live_url that must be changed in order to fix this. We had restored a production instance of Sitefinity in our test environments to test a Sitefinity upgrade, not knowing that the Sitefinity db kept domain name records.
The configuration that Veselin was talking about overrides that live_url property (although I could never get that override to work properly). What's odd is that we had restored over the test db with production db months ago and were never presented with an issue. It wasn't until we had multiple sites hitting the same db that the issue presented and even after removing the second site would not go away.
Anyway, updating the sf_sites table is what did the trick. Please add this to your check list if you need to copy one environment's Sitefinity db into a new environment.

Virtual directory in the project

In IIS under the site I can create a virtual directory which has a different phisical path.
Can I somehow do the same in ASP.NET MVC project? Something like adding a directory which links to a different directory.
The problem is I have some folder outside the site which contains images. I added that folder in IIS under site as Dropbox, which points to completely different location:
Now I also use such paths in the app with Server.MapPath:
"~/Dropbox/Dev/Product/Images"
This all works when I publish in IIS. But how can I do the same locally debugging? Is there a way to add virtual directory to my project in Visual Studio?
I am assuming that your are running your website using IIS Express. You can find your website IIS Express configuration file by right clicking the IIS Express tray icon and then show all applications. Select your website and then click on the config path as shown in screenshot
In config file, find your website site element and then you can add new virtualDirectory element like this:
<site name="Website1" id="2">
<application path="/" applicationPool="website1">
<virtualDirectory path="/" physicalPath="D:\Projects/Website1" />
<virtualDirectory path="/Images" physicalPath="C:/Images" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:54558:localhost" />
/bindings>
</site>
Here you can see Images virtual directory is added.

set base path in IISExpress and webapi in ASP.NET 5

I need to have WebAPI project working under different base path than usual. I created simple project under Visual Studio that uses WebAPI and ASP.NET 5.
Under base path set to http://localhost:38170/ my project works fine and I'm able to get values from test controller (http://localhost:38170/api/values).
At this stage my IIS Express configuration is:
<site name="WebApi" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\WebApi\src\WebApi\wwwroot" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:38170:localhost" />
</bindings>
</site>
I tried changing App URL under project properties to reflect my need:
http://localhost:38170/xxx
Now running project and hitting http://localhost:38170/xxx/api/values results in 404. Trying http://localhost:38170/api/values returns values from controller just as if nothing changed. I noticed that changes in Visual Studio are not reflected in IIS Express configuration (I don't know if they should be...) in any way.
I tried changing path on IISExpress manually like in this thread: Creating virtual directories in IIS express.
<site name="WebApi" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/xxx" physicalPath="C:\WebApi\src\WebApi\wwwroot" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:38170:localhost" />
</bindings>
</site>
The results are:
http://localhost:38170/api/values - 500.19 Error (config error) and that is fairly ok - I don't plan this to work
http://localhost:38170/xxx/api/values - 502.3 - Bad Gateway on hitting httpPlatformHandler
I suppose that error is somewhere in httpPlatformHandler configuration but I'm not sure how to do it in conjuction with IIS Express. My web.config is:
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
</system.webServer>
</configuration>
I tried random changes like changes in path attribute to xxx/* but nothing works.
EDIT:
To clarify the question.
How to setup WebAPI on ASP.NET 5 (ASP.NET Core) on IISExpress using httpPlatformHandler and Kestrel to set base path other than root.
You corrupt the file as your modification does my honor the IIS Express configuration rules.
I will suggest you use a smart tool such as Jexus Manager to manipulate it, and then you can sync the Visual Studio project with the correct URL.
For example, the 404 is expected, as your application tag has path set to /, so there is no application nor virtual directory to serve xxx.
The 500.19 later is also expected, as while adding a valid virtual directory named xxx, you deleted the root virtual directory. That's totally wrong as a root virtual directory must present.

ASP.NET HTTP error 500.19 "cannot read config file"

I have a really frustrating problem. I have a website in ASP.NET. I use IIS Express for development. I recently moved my project files and folders from a usb drive to my dropbox folder to avoid carrying the drive around.
After moving my project to the dropbox folder, I got this error that IIS cannot read my config file. I noticed the path was pointing to my usb drive. So I copied my web.config to the path displayed in the error message and it worked again, if I delete it again, the error comes again.
So I think that somewhere in my project there is a config setting that points to my usb drive, although it should point to my local dropbox folder.
I have attached a screenshot of the error:
Translation:
Module IIS Web Core
Message Unknown
Handler still undetermined
Error code 0x80070003
Config error The config file cannot be read
Config file .........
Requested URL ...........
Physical path
Authentication method still unknown
Authenticated user still unknown
Debug path ..................
I had this problem when trying to launch a service from a project created on another machine that was saved in DropBox.
In the project folder there is a file in PROJECTFOLDERNAME/.vs/config/applicationhost.config
In that file is a list of sites in XML like so:
<sites>
<site name="WebSite2" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Users\WRONGPATH\Dropbox\Website2\src\Website2" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:64655:localhost" />
</bindings>
</site>
<site name="WebSite4" id="3">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Users\Nick\Dropbox\Website3\src\Website3" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:64655:localhost" />
</bindings>
</site>
<siteDefaults>
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
</siteDefaults>
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
<virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>
Change the virtualDirectory physicalPath to the correct path. The problem I still face is I work on this project from two different locations, I don't really want to change this back and forth all the time.
Uhh, I have looked for the answer for more than 2 hours. I tried cleaning up every bin, .vs folders. But those did not help me.
Eventually, I fixed the issue by re-showing (re-binding) the path to the project in IIS Manager
I had this issue when I moved my "My Documents" folder to another location. IIS Express was still pointing to old path. The only way I could fix this is by doing clean installation of IIS Express.
Uninstall IIS Express
Remove the 'IIS Express' folder that contains configuration file.
Install IIS Express

How to recycle app pool on a specific time during work days?

Is it possible to schedule an App Pool recycle on a specific time only during work days?
Thanks in advance!
In case you can't configure the desired schedule using IIS directly, you could create a scheduled task that invokes
c:\Windows\system32\inetsrv\appcmd.exe recycle apppool "NameOfTheAppPool"
at the required times.
If you are using IIS 7, PeriodicRestart is the key. Add the following into your ApplicationHost.config file:
<add name="YourApplicationPool">
<recycling logEventOnRecycle="Schedule">
<periodicRestart>
<schedule>
<clear />
<add value="12:00:00" />
</schedule>
</periodicRestart>
</recycling>
<processModel identityType="NetworkService" shutdownTimeLimit="00:00:30" startupTimeLimit="00:00:30" />
</add>
It will recycle your Application Pool at 12 o'clock each day.
If you are using IIS7, you could setup a Scheduled Task, for the work days, running the following command:
appcmd.exe recycle apppool "YourApplicationPool"
If you are using IIS6, I'd follow the guide here.
This documentation illustrates how to use app pool recycling settings.
<add name="Contoso">
<recycling logEventOnRecycle="Schedule">
<periodicRestart>
<schedule>
<clear />
<add value="03:00:00" />
</schedule>
</periodicRestart>
</recycling>
<processModel identityType="NetworkService" shutdownTimeLimit="00:00:30" startupTimeLimit="00:00:30" />
</add>
If you are hosting in Azure, you could use a startup.cmd file with the following (from here):
REM Prevent unwanted recycling
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.recycling.periodicRestart.time:00:00:00
REM Recycle every day at 4am
%windir%\system32\inetsrv\appcmd set config -section:system.applicationHost/applicationPools /+applicationPoolDefaults.recycling.periodicRestart.schedule.[value='04:00:00'] /commit:apphost

Resources