MVC area and virtual folders - asp.net

I'd like the ability to add a sub "folder" to an MVC area. For instance, I have an area
~/areas/Support
And, in some classic ASP code, I need to refer to an include file
<!-- #include virtual="/Support/_inc/myinclude.asp"-->
Just for grins I tried including a virtual folder /support that points to this virtual folder, but that, of course, overrides the MVC route and keeps the MVC stuff from executing.
Suggestions?

I've found a solution that seems somewhat unconventional, but is working so far.
Under my test environment (IIS7.5 on Win7 Ultimate 64, ASP.NET MVC2), I edited the config file
c:\windows\system32\inetsrv\config\applicationHost.config
and added virtual folders like so
<virtualDirectory path="/Support/_inc" physicalPath="C:\websites\virt\...\support\_inc" />
<virtualDirectory path="/support/man" physicalPath="c:\websites\http\...\support\man" />
<virtualDirectory path="/support/man/docs" physicalPath="c:\websites\virt\...\support\man\docs" />
<virtualDirectory path="/Support/docs" physicalPath="C:\websites\virt\...\support\docs" />
<virtualDirectory path="/Support/man/_inc" physicalPath="C:\websites\virt\...\support\man\_inc" />
since there is no virtual folder (or real folder, for that matter) at /support, MVC routes that to the /Areas/Support... items. Anything that matches the virtual folders in the application config, however, seem to be routed by IIS before ASP.NET takes over, so they are correctly handled by ASP.
Interesting.

Related

ASP.NET MVC request handled by StaticFile handler because of AppPool configs?

Sometimes, on my Windows 7 laptop, my ASP.NET MVC applications would fail with an error like:
HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory.
Detailed Error Information
Module DirectoryListingModule
Notification ExecuteRequestHandler
Handler StaticFile Error
At the same time other MVC applications worked fine. So, I knew I had everything installed correctly. I tried the ideas in ASP.NET MVC on IIS 7.5 but none worked for me.
My guess was that MVC or ASP.NET was not configured correctly, so IIS did not interpret the URL correctly and map it as an MVC application that should use routing. The correct HttpModule was not being found, so IIS was treating the request as for a static page and redirecting to the folder, but since directory browse was not enabled, I was getting the error.
I finally stumbled around my file system and noticed two directories with config files:
C:\inetpub\temp\appPools\DefaultAppPool\DefaultAppPool.config
C:\inetpub\temp\appPools\ASP.NET V4.0 Integrated\ASP.NET V4.0 Integrated.config
These config files contained a bunch of incorrect application definitions. Some of these were for applications that did not show up in IIS Manager. Here is an example of two (one is incorrect, one is correct):
<system.applicationHost>
<sites>
<site name="Default Web Site" id="1" serverAutoStart="true">
<application path="/appsuite/billing/customer/log-in" applicationPool="ASP.NET V4.0 Integrated">
virtualDirectory path="/" physicalPath="C:\dev\appsuite\trunk\appsuite.Services\Billing\src\Billing" />
</application>
<application path="/appsuite/billing" applicationPool="ASP.NET V4.0 Integrated">
<virtualDirectory path="/" physicalPath="C:\dev\appsuite\trunk\appsuite.Services\Billing\src\Billing" />
</application>
My problem was when I attempted to request a URL that matched one of these apps with a bad path, like http://localhost/appsuite/billing/customer/log-in, I would get the 403 error.
I deleted everything in C:\inetpub\temp (I figured, hey it's a temp folder) and after hitting my url, the config files came back. I then manually deleted from the config file the applciation that matched my url and the app started working.
Where do the settings for these config files come from, where is the data coming from after I deleted them?
How can I clean up the old junk that is in them that isn't used any more?
I suspect I created this mess in Visual Studio. Sometimes when setting the Web properties of a project, I would accidentally set the Project URL to my launch URL, when I really meant to set the Start URL to this value. My guess is this set up a new web app with the url that matched my start page.

Adding a webServer handler causes duplicate key error in IISExpress when virtual path specified

I have an MVC5 app in VS2013. I need to add some handlers to the root Web.config. This works fine with no virtual directory, but when I specify a virtual directory, IIS Express fails.
This is easy to reproduce in VS2013:
Create a new ASP.NET Web Application. Select MVC and no authentication
edit the top level Web.config. Add the following lines to the bottom, right before the closing configuration tag:
<system.webServer>
<handlers>
<add verb="GET" path="*.png" name="Static for png"
type="System.Web.StaticFileHandler" />
</handlers>
</system.webServer>
</configuration>
The application will run fine. Now, go to the Project properties, "Web" tab, and add an application name like "WebTest" to the project Url. Click the "Create Virtual Directory" button and acknowledge so that VS will let you save.
build and run
You get an error 500.19 - Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'Static for png' .
IIS Express is running the app at two URLs, one with the name and one without. The URL without the name (http://localhost:52065/) comes first and works fine; the one with the name comes second and has the error. By the way, VS2010 just runs the app with the name and this works fine.
Poking in the MyDocuments\IISExpress\config\applicationhost.config file, I see the two entries for the app, both pointing to the same physical directory:
<site name="WebTest" id="3">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\_Dev\WebTest\WebTest" />
</application>
<application path="/WebTest" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\_Dev\WebTest\WebTest" />
</application>
I don't understand why there need to be two entries. I tried:
removing the first application entry. This causes an unrecognized
configuration path error.
duplicating the entire solution, and pointing the first entry at it. This gets the same duplicate error.
Some Context: I need the static handlers because this app has to be structured as a collection of independent dlls. I embed the content into the dlls
at build time and then use a VirtualPathProvider to intercept each path request and return a stream from the dll. I've found that this only works if the static file handler is in the root Web.config; otherwise my VPP doesn't get the request.
The dlls are in a Plugin directory under the project root directory. Putting a config file there didn't help either.
What am I missing? Is there a way to get IIS Express to run the app only with a name and avoid the duplicate key error?
You must always keep in mind, that ASP.NET applications under the same web site inherit parent's configuration. That means, the WebTest application will have one "Static for png" from itself, and another "Static for png" from its parent (the site root application).
Thus, as #hobwell pointed out, you must add a tag to avoid duplication.

VS 2013 / IIS Express - serve site from localhost:port/myapp instead of localhost:port

In prod my site (mvc5) is hosted on https://company.no/myApp/ where myApp is an Application on IIS.
In dev my site is hosted on IIS Express on http://localhost:54307/
As this causes some truble with server relative paths I would like to also do my debugging on http://localhost:54307/myApp.
This is what I've tried:
Setting project url in property pages to http://localhost:54307/myApp and clicking Create Virtual directory
Tried the override application root with or without the myApp url.
Tried modify the applicationhost.config. Currently my setting looks like this:
<site name="MyApp.Web-Site" id="38">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Projects\OP\MyApp\Main\src\MyApp.Web" />
</application>
<application path="/MyApp" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Projects\OP\MyApp\Main\src\MyApp.Web" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:54307:localhost" />
<binding protocol="https" bindingInformation="*:44307:localhost" />
</bindings>
</site>
When I try to open page from the myApp folder I get the follownig error:
Module IIS Web Core
Notification BeginRequest
Handler Not yet determined
Error Code 0x800700b7
Config Error Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'WSFederationAuthenticationModule'
Config File \\?\C:\Projects\OP\MyApp\Main\src\MyApp.Web\web.config
Requested URL http://localhost:54307/MyApp
Physical Path C:\Projects\OP\MyApp\Main\src\MyApp.Web
That indicates web.config loaded twice. Any idea what I'm doing wrong?
Thanks for any help
Larsi
I hear you with IIS Express causing problems with server relative paths. You can set this up with a couple steps that don't include manually editing your applicationhost.config. I try to avoid editing the applicationhost.config manually, it seems to cause more problems than it solves. I would remove the website from your local IIS to clear out any of that stuff and then do the steps below:
right-click on your web project and select properties.
Click on the "Web" menu
change the dropdown to Local IIS and enter the URL you would like the app to resolve to then click create virtual directory, save the file and build.
You can still debug without the port number, the debugger will just attach to this new website in your local IIS instance as long as you have a debugger option checked on the web tab.
open your local IIS and make any other configurations that are required for your app to run (Authentication, Application Pools, etc.).
open your browser and navigate to http://localhost/YourAppName
since this is a website as far as your local iis is concerned, you can hit it anytime in a browser without needed Visual Studio running.

Visual Studio 2012 Launches Wrong Project For Debugging

I've got an ASP.NET web application project in a Visual Studio 2012 solution. I'll refer to this as A.
I copied A's directory to a new directory to make a clone of it. I'll refer to this as B.
I made extensive changes to both A and B to the point that they are not even remotely similar. Stylesheets, scripts, HTML, and back end is all different.
I launched A for debugging, and it appeared in my browser as expected. I debugged the application for awhile, and then terminated debugging via the "stop debugging" icon on the toolbar within Visual Studio 2012.
I then launched B for debugging. Instead, I got A.
I tried clearing browser cache, though, this couldn't be the problem because the server side of the application was wrong too.
I tried Rebuilding the project, after running Clean. I still see A while trying to debug B.
I tried killing all processes related to the debugging session including all iisexpress.exe, MSBuild.exe, WebDev.WebServer40.EXE, Microsoft.VisualStudio.Web.Host.exe instances.
I tried closing Visual Studio 2012 completely, reopening it, and retrying debugging.
EDIT
After closing and reopening VS2012 for a third time, it started now allowing me to see B. Nothing else has changed.
Best I can come up with is there must be some type of project setting that needs to be changed to reflect that the project lives in a different space than it did before being copied, but I have yet to track down such a setting.
What am I missing?
I have just come across this issue today, having done exactly as you (copied a project, and then edited). And hence i would like to share my solution.
If you go to Project B's Properties (found in solution Explorer), you will find a Web tab:
In your Servers section, alter the Project Url to:
http://localhost: + (number +1) + /
and then hit Create Virtual Directory
You should then be able to re-run your project and since they're running off different Url's, you shouldn't see this clash again.
I was in the exact same situation. The problem was that both projects (Project_A & Project_B) we’re setup to run on the same port in IIS Express.
IISExpress determines the port/application by looking at a configuration file located in <Documents>\IISExpress\config\application.config.
Open that file and look for a section <sites>. You should find a list of your VS projects. Locate your projects (A and B) and make sure that both projects are not running on the same port
<site name="Project_A" id="17">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Projects\Somefolder\ Project_A " />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:64212:localhost" />
</bindings>
</site>
<site name="Project_B" id="18">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\Projects\Somefolder\ Project_B " />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:64212:localhost" />
</bindings>
</site>
If that is the case, remove one entry (i.e. Project_B), and then go in Visual Studio to recreate the entry.
In VS, go in the Properties of Project_B. Click on Web tab and look for the “Servers” section.
Enter a new port (i.e. `http://localhost:64213`) and click on the “Create Virtual Directory” button. This will add an entry in the “application.config” file, with the new association (i.e. Project_B / port 64213)
This should fix the problem. Hope this helps
This question is not marked as answered and as I had a similar problem I thought I would answer it.
you need to go to project > properties > web then check the use local web server box and overide application root if applicable, change the path names to the ones you are using save and it should work.

Application's AppPool permisions on parent Site folder structure

ApplicationHost.config Context
<!-- App Pool -->
<add name="Site - Intranet" autoStart="true" managedRuntimeVersion="v4.0" />
<add name="App - App1" autoStart="true" managedRuntimeVersion="v4.0" />
<add name="App - App2" autoStart="true" managedRuntimeVersion="v2.0" />
<!-- Site -->
<site name="Intranet" id="1" serverAutoStart="true">
<application path="/" applicationPool="Site - Intranet">
<virtualDirectory path="/" physicalPath="D:\Web\Sites\Intranet" />
</application>
<application path="/Apps/App1" applicationPool="Application - App1">
<virtualDirectory path="/" physicalPath="D:\Web\Apps\App1" />
</application>
<application path="/Apps/App2" applicationPool="Application - App2">
<virtualDirectory path="/" physicalPath="D:\Web\Apps\App2" />
</application>
</site>
As you can see, I have one Site with its own 4.0 CLR app pool and identity, which hosts two separate Applications, each with their own app pools and identities. All three are sandboxed into separate file system locations.
NTFS Permissions for AppPoolIdentity Accounts
Permissions must be given to each AppPoolIdentity on its respective folder (ex. IIS AppPool\Site - Intranet needs Read/Execute permissions on D:\Web\Sites\Intranet).
At this point, Application App1 should not be able to read/execute files in it's parent Site's physical folder structure. And vice versa, the hosting Site Intranet should not be able to read/execute files within App1's physical folder structure. Am I understanding that right?
When I visit a child application (ex http://intranet/apps/app1) I get a server error stating that it cannot read the parent Site's web.config file due to insufficient permissions.
If I grant the Application's identity account read/execute permissions on the parent Site's physical folder structure (ex. IIS AppPool\App - App1 access to D:\Web\Sites\Intranet) the issue is resolved.
Question(s)
Why does the child Application need to read web.config or any other files from the parent site?
Note: My parent site's web.config is already breaking child app/vdir inheritance using the <location path="." inheritInChildApplications="false"> technique.
Given that this identity account has by nature Write permissions on many folders - IIS AppPoolIdentity and file system write access permissions - doesn't this introduce a security risk? For instance, couldn't any child application now potentially write to the parent Site's App_Data folder or elsewhere?
For #1, child folders/apps inherit the web.config settings of their parent folders by default. I would assume that ASP.NET doesn't check your element before trying to access those parent web.config files. Makes sense to me though it's not what you would want.
For #2, not too sure there. If your app pool identity is a member of users (as your references answer states) then it does have read access to lots of places, but not write to too many. I wouldn't go by what the questioner says there. Not sure about the child writing to parent folders. You should be able to block that with appropriate file system permissions (keeping in mind whatever groups your app pool identity is a member of). I've never had this config so I'm not sure.

Resources