I recently had to create a website within an MVC application on Azure, but ran into quite a few problems. Being Azure, you are pretty limited to what you can and can't do regarding customizing permissions on folders for Azure web apps, unlike the traditional IIS management console that we all love and adore on a traditional windows box.
What I really didn't know was how to upload an existing web application, and run it under an existing web application in Azure. There are resources online which show you how to create web apps from scratch, but there really isn't that much information about creating a web application, in a sub-folder in an existing web site.
Uploading a sub application and creating a virtual directory on Azure didn't work as one would expect. It just didn't work for the app that I was uploading. However, after a few hours of experimenting, I ended up getting it up and running and I thought I would share my learnings. If it helps you, then great!
After watching the error appear on the screen, I thought, Ok, how would I get this up and running as if I were doing this locally within IIS.
- Essentially, all I would do in IIS would be
- Create a virtual application under an existing web site
- Set up all of the IIS requirements (e.g permission, app pool process etc)Set up the ACL for the folders which I want to be read/written to.
- Restart the site (just to be sure) and off we go
Now, on the Azure side, this doesn't really happen the same way. Firstly, you do have the option of creating virtual applications under Azure, so I knew they must support this feature. So I created a virtual application using the folder location of where it would exist (note it has to be the name of the folder you will navigate to within the web application). Because it's going to be an application in itself, you have to ensure that the "Application" option is checked.
But how do I set the application specific settings on folders? First thing I did, was FTP into the Azure website and uploaded the application into this folder where I created the virtual director. Once complete I set the folder permissions within the FTP session and went to the sub application's URL and "Boom". It had an error still relating to the write permissions of the App_Data folder in the sub application's directory.
How do I set the permissions? I remember using webmatrix and from memory, its behaviour was when you deployed a website into a server, it would take the existing ACL, and apply that into the destination folder on your server. I was using Visual Studio, so I looked around and saw the "Webdeploy" publish option. That looked promising. What I had to do was:
- From within the Azure portal download the Azure publish profile to a location on the local PC.
- Within Visual Studio, right click the web project and from the context menu, select "Publish.."
- Once the Publish Web dialog pops up, select "Import" option and navigate to where you saved the publish profile, from the previous step
- Follow the steps that the wizard provides you, but one thing to note, that the publish location on the sever, must include the name of the folder that you want it to be published to. If you do not do this, then the publish will publish at the root level of your web site and clobber everything that it finds! Trust me, it happened to me.
After Publish it still didn't work
After publishing to the server, I opened up the URL and "Boom". It was still erroring, this time with a different error, not a write permission to a folder error. The main site was fine and working normally, so it looked like it was something to do with the sub sites configuration.
I removed the main site from Azure (it was just a test environment) and went to the sub application URL and it worked. I thought, the parent site must be upsetting the subapplication. So I did an internet search about Sub applications within an existing ASP.NET website and read up on what elements are included in web.config.
According to the microsoft web.config documentation, there is an element which gets or sets a value that indicates whether the settings that are specified in the associated configuration section are inherited by applications that reside in a sub directory of the relevant application. I added this to my main sites web.config as follows
<location path="." inheritInChildApplications="false">
<authentication mode="None" />
<compilation targetFramework="4.5" />
<httpRuntime targetFramework="4.5" enableVersionHeader="false"/>
<globalization uiCulture="en-GB" culture="en-GB" />
<customErrors mode="On" >
<error statusCode="404" redirect="~/Errors/404.html"/>
<remove name="FormsAuthenticationModule" />
<!-- custom module to remove any unwanted header values going back to clients -->
<add name="HttpHeadersCleanup" type="DingbatStudios.Web.Site.Common.HttpHeadersCleanup, DingbatStudios.Web.Site, Version=220.127.116.11, Culture=neutral" />
I then went to the subfolder URL and it worked! I thought great, problem solved. I then clicked around testing the app, but I then received an error on one of the pages saying "You do not have permission to view this page". Hey, this was working before when it existed without the parent app. Why isn't it serving up this page? I thought it must have something to do with the parent site again. I opened up the parent site's web.config and had a look and saw the appSettings key="webpages:Enabled" value="false". Because my app was a MVC app, the default template for this site, disables .aspx files from running. So I changed it to be true.
<add key="webpages:Version" value="18.104.22.168" />
<add key="webpages:Enabled" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="log4net.Internal.Debug" value="true" />
<add key="log4net.Config" value="log4net.config" />
<add key="CacheTimeInSeconds" value="3600"/> <!-- 1 hour -->
I then opened up the sub applications's URL and tested what was failing before and it all worked. Yay, after about 3 hours it was finally working.
So in summary, the steps that I found to uploading an existing ASP.NET Webforms application into and existing ASP.NET MVC 5 application is as follows
Summary of Steps
- In Azure, create the virtual directory, ensure that web application option is checked
- Download the Azure website's webdeploy configuration to local machine
- Use Visual Studio to deploy the application, along with any customized ACL on folders that you need into the virtual directory folder on your server
- Update the web application (main website) to use the <location path="." inheritInChildApplications="false"> element
- Update the web application (main website) app configuration's key to be true e.g. <add key="webpages:Enabled" value="true" />
I hope that this may be of use to someone else facing the same issues.