0
votes

I am working on a pluggable ASP.NET MVC web app that discovers and registers areas at runtime from the Areas directory.

My problem is that the view engine does not find any views from that area.

I have one partial view located at

~/Areas/Catalog/Views/Shared/_SearchBarPartial.cshtml

I set the area using:

htmlHelper.ViewContext.RouteData.DataTokens["area"] = "Catalog";

But when executing

Html.Partial("_SearchBarPartial")

I get the following error:

The partial view '_SearchBarPartial' was not found or no view engine supports the searched locations. The following locations were searched:

~/Areas/Catalog/Views/Home/_SearchBarPartial.aspx ~/Areas/Catalog/Views/Home/_SearchBarPartial.ascx ~/Areas/Catalog/Views/Shared/_SearchBarPartial.aspx ~/Areas/Catalog/Views/Shared/_SearchBarPartial.ascx ~/Views/Home/_SearchBarPartial.aspx ~/Views/Home/_SearchBarPartial.ascx ~/Views/Shared/_SearchBarPartial.aspx ~/Views/Shared/_SearchBarPartial.ascx ~/Areas/Catalog/Views/Home/_SearchBarPartial.cshtml ~/Areas/Catalog/Views/Home/_SearchBarPartial.vbhtml ~/Areas/Catalog/Views/Shared/_SearchBarPartial.cshtml ~/Areas/Catalog/Views/Shared/_SearchBarPartial.vbhtml ~/Views/Home/_SearchBarPartial.cshtml ~/Views/Home/_SearchBarPartial.vbhtml ~/Views/Shared/_SearchBarPartial.cshtml ~/Views/Shared/_SearchBarPartial.vbhtml

My folder structure is:

bin/
Areas/
    Catalog/
        bin/
            CatalogArea.dll
        Content/
        Scripts/
        Views/
            Shared/
                _SearchBarPartial.cshtml
         CatalogArea.cs
Content/
Scrips/
Views/
Global.asax

To register areas i use the following code, executed before application start:

   [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Bootstrapper), "LoadAreas")]

    public class Bootstrapper
    {

        public static string ModuleDirectory
        {
            get { return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Areas"); }
         }

        public static void LoadAreas()
        {
            var assemblyFiles = Directory.GetFiles(ModuleDirectory, "*.dll", SearchOption.AllDirectories);

            assemblyFiles.ForEach(af =>
            {
                var assembly = Assembly.LoadFile(af);
                if(assembly.GetTypes().Any(t => IsArea(t))
                {
                    BuildManager.AddReferencedAssembly(assembly);
                }
            });
        }

        private static bool IsArea(Type t)
        {
            return typeof (AreaRegistration).IsAssignableFrom(t) && !t.IsAbstract;
        }
    }

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        // ...
     }
 }
1

1 Answers

1
votes

You can add your custom RazorViewEngine in Global.asax.cs. Example:

RazorViewEngine objRazorViewEngine = new RazorViewEngine();
objRazorViewEngine.PartialViewLocationFormats = new string[]
{
"~/Areas/Catalog/Views/Shared/{0}.cshtml"
};
ViewEngines.Engines.Add(objRazorViewEngine);