从外部库加载时找不到强类型视图

时间:2014-03-10 14:41:22

标签: asp.net-mvc asp.net-mvc-4

背景

我有一个MVC 4应用程序,我试图融入可插拔架构。我在Areas目录中加载名为“VS.Web.IPortal.Apps。*。dll”的dll。

问题

这一切都有效,除非使用强类型视图。是否有任何故障排除或调试方法可以帮助理解正在做什么来“找到”MVC路由引擎正在寻找的视图?

底部的错误

代码

这是与我正在做的相关的代码。

PluggableInterface.dll

标准类库,具有一个类ApplicationDynamicDiscovery。

属性/ AssemblyInfo.cs中

[assembly: PreApplicationStartMethod(typeof(ApplicationDynamicDiscovery), "Discover")]

ApplicationDynamicDiscovery.cs

public static class ApplicationDynamicDiscovery
{        
    /// <summary>
    /// Discover all dlls that meet the spec in the path. This is static, so that it happens
    /// before startup - this works.
    /// </summary>
    public static void Discover()
    {
        var areasDir = new DirectoryInfo(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Areas"));

        if (!areasDir.Exists)
        {
            return;
        }

        var assemblies = areasDir.GetDirectories()
                .SelectMany(d => d.GetDirectories("bin", SearchOption.TopDirectoryOnly))
                .SelectMany(d => d.GetFiles("VS.Web.IPortal.Apps.*.dll", SearchOption.TopDirectoryOnly))
                .Select(f => Assembly.LoadFile(f.FullName));

        // register all the assemblies.
        assemblies.ToList().ForEach(BuildManager.AddReferencedAssembly);
    }
}

MainMvcApp 主应用程序没有任何自定义代码 - 它是使用MVC 4 Internet应用程序模板创建的。 创建项目对PluggableInterface.dll的引用。

MvcApp 在MainMvcApp的Areas文件夹中创建此项目。

MvcAppAreaRegistration.cs

namespace VS.Web.IPortal.Apps.MvcApp
{
    public class MvcAppAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "MvcApp";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            // Default route
            context.MapRoute(
                    "MvcApp_default",
                    "MvcApp/{controller}/{action}/{id}",
                    new { action = "Index", id = UrlParameter.Optional },
                    new string[] { "VS.Web.IPortal.Apps.MvcApp.Controllers" }
                );
        }
    }
}

控制器/ MvcAppController.cs

namespace VS.Web.IPortal.Apps.MvcApp.Controllers
{
    public class MvcAppController : Controller
    {
        public ActionResult Index()
        {
            return this.View(new MvcAppModel { Name = "Test" });
        }
    }
}

模型/ MvcAppModel.cs

namespace VS.Web.IPortal.Apps.MvcApp.Models
{
    public class MvcAppModel
    {
        public string Name { get; set; }
    }
}

查看/ MvcApp / Index.cshtml

@model VS.Web.IPortal.Apps.MvcApp.Models.MvcAppModel

<h2>title - @Model.Name </h2>

有了这个 - 我可以启动服务器并浏览到localhost:port / MvcApp / MvcApp我收到以下错误

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Areas/MvcApp/Views/MvcApp/Index.aspx
~/Areas/MvcApp/Views/MvcApp/Index.ascx
~/Areas/MvcApp/Views/Shared/Index.aspx
~/Areas/MvcApp/Views/Shared/Index.ascx
~/Views/MvcApp/Index.aspx
~/Views/MvcApp/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Areas/MvcApp/Views/MvcApp/Index.cshtml
~/Areas/MvcApp/Views/MvcApp/Index.vbhtml
~/Areas/MvcApp/Views/Shared/Index.cshtml
~/Areas/MvcApp/Views/Shared/Index.vbhtml
~/Views/MvcApp/Index.cshtml
~/Views/MvcApp/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml 

如果我从视图中移除@model VS.Web.IPortal.Apps.MvcApp.Models.MvcAppModel,它就可以正常工作。 如果我删除对PluggableInterface项目的引用并添加MvcApp项目,它将与强类型模型一起使用。 任何可以指出我如何解决此路由问题的人都将不胜感激。

1 个答案:

答案 0 :(得分:1)

我通过在添加它们之后跟踪程序集,然后添加程序集解析程序来解决这个问题。我不知道它是否是最佳解决方案,但它似乎可以解决问题。

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve;
ApplicationDynamicDiscovery.Assemblies = new List<Assembly>();

CurrentDomainAssemblyResolve函数:

    /// <summary>
    /// Look through the dynamically loaded assemblies, when looking for an assembly.
    /// </summary>
    private static Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (args.RequestingAssembly != null)
        {
            return args.RequestingAssembly;
        }

        // might return null
        return ApplicationDynamicDiscovery.Assemblies.SingleOrDefault(x => x.FullName == args.Name);
    }