Question

So I've been tinkering with View locations for an MVC app I'm working on, specifically because I need to be able to use views/routes for a parent site in a child site.

Ultimately I want to be able to serve up views from a different location, say ~/SiteAViews/.. Where ~ is the root of site B, and the views deposited in site ~/SiteAViews/ are views copied in a post build event from SiteA.

Sounds easy with a custom view engine. However, I've done this in a custom view engine (example change below) adding to the locations for the view and master pages. The problem occurs when accessing a URI, and therefore route that is defined in the SiteA dll (referenced in siteB).

this.ViewLocationFormats = new string[8]
{
    "~/Views/{1}/{0}.aspx",
    "~/Views/{1}/{0}.ascx",
    "~/Views/Shared/{0}.aspx",
    "~/Views/Shared/{0}.ascx",

    "~/SiteAViews/{1}/{0}.aspx",
    "~/SiteAViews/{1}/{0}.ascx",
    "~/SiteAViews/Shared/{0}.aspx",
    "~/SiteAViews/Shared/{0}.ascx"
};

If I change the view engine, and post build task, to refer to/copy content to ~/views/SiteA/.. rather than ~/SiteAViews/.. it all works great and parses the ViewModel. However, with ~/SiteAViews/.. I receive the following.

Exception type: HttpParseException Exception message: Could not load type 'System.Web.Mvc.ViewPage<'Shared.MyViewModel'>'. at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseFile(String physicalPath, VirtualPath virtualPath) at System.Web.UI.TemplateParser.Parse() at System.Web.Compilation.BaseTemplateBuildProvider.get_CodeCompilerType() at System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(BuildProvider buildProvider) at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)

Was it helpful?

Solution

You are missing the information in web.config file found in the Views folder. In asp.net the configuration for a given folder will be resolved following this hierarchy of web.config files:

machine.config -> root application web.config -> subdirectory web.config

In the case of asp mvc, the web.config file in the Views folder will configure the default namespaces to be included when compiling each view into its class and a default handler that prevents the view files from being directly accessed. See this question.

As you have created another directory SiteAViews in the root of your project (i.e. outside the Views folder), you are missing the basic mvc configuration that ~/Views/web.config provides. You could fix it by copying ~/Views/web.config into ~/SiteAViews/web.config. (If you were using Razor you may want to copy the _ViewStart.cshtml file as well)

If you don´t like having to maintain 2 similar config files you will need to create a view folders hierarchy with a common root where you can put the web.config file (and adjust your view engine accordingly):

~/ViewLocations/web.config     //common asp mvc views config
~/ViewLocations/Views/         //SiteB views
~/ViewLocations/SiteAViews/    //SiteA views

//In your view engine:
this.ViewLocationFormats = new string[8]
{
    "~/ViewLocations/Views/{1}/{0}.aspx",
    "~/ViewLocations/Views/{1}/{0}.ascx",
    "~/ViewLocations/Views/Shared/{0}.aspx",
    "~/ViewLocations/Views/Shared/{0}.ascx",

    "~/ViewLocations/SiteAViews/{1}/{0}.aspx",
    "~/ViewLocations/SiteAViews/{1}/{0}.ascx",
    "~/ViewLocations/SiteAViews/Shared/{0}.aspx",
    "~/ViewLocations/SiteAViews/Shared/{0}.ascx"
}; 

Hope it helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top