This is the scenario which has been working for years. I have a parent asp.net web application at (say) www.MySite.co.uk and under it I have multiple child (client) sites in virtual directories e.g. www.MySite.co.uk/Client1 etc. All sites (parent and child virtual directories) are traditional asp.net web forms applications using .NET 4.5 and all working fine.
Yesterday, I updated my parent site to be an asp.net MVC 5 web application (developed for me by a freelancer). I only updated the parent site and it broke all my child sites. As an emergency fix for this I have renamed the web.config file in my parent MVC site, obviously this has broken my parent site, but at least the client (child) sites are working again.
There is obviously a setting in the root application (the MVC one) which the webforms sites are inheriting and they don’t like it.
In my research I came across this: http://forums.iis.net/t/1200821.aspx?Creating+virtual+directory+for+ASP+NET+website+under+MVC+application and so I wonder if the setting in question is to do with my MVC RouteConfig.cs file. My freelancer set it up so that old links to my aspx paths would still work (i.e. map to my new views). I'm not familiar with the code yet, but here is a snippet:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "HelpRedirect",
url: "Help/{*route}",
defaults: new { controller = "Help", action = "ViewRedirect" }
);
routes.MapRoute(
name: "AspxRoute",
url: "{controller}/{action}.aspx",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "ContactRoute",
url: "Contact.aspx",
defaults: new { controller = "Contact", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
I have done a lot of searching, but so far have been unable to find out the solution. So my question is this:
I would be very grateful if anyone could point me in the right direction, thanks in advance.
Update
Having also looked at this post Virtual Directory App within a Asp.net MVC app I have tried editing web.config in the root application and wrapping <location inheritInChildApplications="false">
around everything that would allow it. But it did not work, the client sites still didn't work.
Update 2
I have a response from my freelancer who says it is about routing and URL because MVC expects something to be at /Client1 etc. So we need to write a route which sends such requests (route plus one word) to a controller which then needs to see whether this is a page in the MVC (e.g. /help) or a client site (e.g. /Client1) and display appropriate page.
Personally I don't know enough about routing to do this myself, but my freelancer is on the case. If he comes up with a solution I will post it. I would still appreciate any other input or alternative solutions.
Update 3
Now solved! Please note, it was nothing to do with MVC, that was a red herring. Thanks to Greg Burghardt for pointing me in the right direction with his comment "Apparently IIS tries matching a virtual directory first, then an MVC controller". This is true, there are no routing issues with having ASP.NET Web Forms sites in virtual directories under an MVC parent site. It was to do with web.config Entity Framework inheritance issues. I will post the answer.
Is MVC suitable for both Windows and Web applications? The MVC architecture is suited for a web application than Windows. For Window applications, MVP, i.e., “Model View Presenter” is more applicable.
Virtual directories and applications are now separate objects, and they exist in a hierarchical relationship in the IIS configuration schema. Briefly, a site contains one or more applications, an application contains one or more virtual directories, and a virtual directory maps to a physical directory on a computer.
Every MVC application must configure (register) at least one route configured by the MVC framework by default. You can register a route in RouteConfig class, which is in RouteConfig. cs under App_Start folder.
To create a virtual directory with IIS Manager for an ASP.NET application. In IIS Manager, expand the local computer and the Sites folder. Right-click the site or folder where you want to create the virtual directory and then click Add Virtual Directory.
Finally solved it!
The answer is yes, it is perfectly fine to have traditional ASP.NET web forms sites in virtual directories under an MVC site parent directory. There are no routing issues, as IIS looks for virtual directories first, before looking at MVC routing.
The problem I had turned out to be to do with web.config file inheritance. With the new MVC site, I had introduced Entity Framework for the first time. So my web.config file contained the following section:
Parent MVC Web.config
<configSections>
<!-- various other sections ... -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
Now my child web forms sites already had the same setting, and it turns out it is not allowed to be specified more that once down the hierarchy. I know about the <location inheritInChildApplications="false">
tag to prevent inheritance, but after experimentation, I've discovered this can't be used on the <configSections>
section. I have also tried the <clear />
tag in the child Web.config, but this doesn't seem to work in <configSections>
either.
So, after following this answer to a similar issue, I managed to solve it by commenting out the various Entity Framework sections in my child Web.config and used unusual binding to also fix version issues (my parent site was using Version 6, but my child sites were using Version 5).
Child Web.config Relevant Snippets:
<configSection><entityFramework>
section commented out:
<configSections>
<!--<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />-->
<entityFramework>
section commented out:
<!--<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>-->
Binding in runtime section to always use version 5:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<!-- This is to get this Virtual Directory to use EF5 even if parent uses EF6 -->
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
It's a bit of a messy solution as my Child web forms sites are not all in a virtual directory beneath the MVC parent site, so in those cases the Entity Framework sections of Web.config would need to be un-commented. If anyone knows a neater solution, that would work regardless of the parent site (or lack of it), please share.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With