从未引用程序集动态加载预编译视图致MVC主应用模型类型识别错误
解决MVC插件预编译视图模型类型无法识别的问题
我之前在做MVC插件化开发时,也踩过这个预编译视图模型识别的坑,给你几个实际可行的解决思路:
一、先搞清楚问题根源
出现这个错误的核心原因是CLR类型隔离:
- 要么主应用和插件的模型类虽然代码一样,但属于不同的程序集,CLR会把它们当成完全不同的类型;
- 要么MEF加载插件程序集时用了独立的加载上下文,导致主应用无法识别插件程序集中的模型类型;
- 还有可能是预编译视图生成时,模型的引用路径出了问题,视图找不到正确的模型类型。
二、针对性解决方案
1. 共享模型程序集(最根本的解决办法)
把主应用和插件共用的模型类,单独抽成一个独立的类库项目:
- 主应用和插件都引用这个类库,而不是各自定义相同的模型;
- 这样两边的模型类型来自同一个程序集,CLR就会识别为同一个类型,不会出现“无法识别模型类型”的错误。
如果必须在插件里定义模型,那要确保插件的模型程序集被主应用正确加载,别用Assembly.LoadFile加载插件.dll(它会把程序集放到独立的加载上下文,导致类型隔离),改用Assembly.LoadFrom:
// 正确的加载方式,把插件程序集加入主应用的加载上下文 var pluginAssembly = Assembly.LoadFrom(@"D:\Plugins\MyPlugin.dll"); var catalog = new AssemblyCatalog(pluginAssembly); var container = new CompositionContainer(catalog); // 导入插件控制器 var pluginControllers = container.GetExportedValues<IPluginController>();
2. 调整Razor Generator视图引擎的配置
自定义一个继承自RazorGeneratorMvcViewEngine的视图引擎,在创建视图时手动确保模型类型的程序集已被加载:
public class PluginRazorViewEngine : RazorGeneratorMvcViewEngine { protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var compiledView = base.CreateView(controllerContext, viewPath, masterPath) as CompiledRazorView; if (compiledView?.ViewDataInfo?.ModelType != null) { // 提前加载模型类型所在的程序集,避免视图找不到类型 var modelAssembly = compiledView.ViewDataInfo.ModelType.Assembly; if (!modelAssembly.IsDynamic) { Assembly.Load(modelAssembly.FullName); } } return compiledView; } }
然后在主应用的Global.asax.cs(或者Startup.cs,看你用的MVC版本)里注册这个自定义视图引擎:
protected void Application_Start() { // 注册自定义视图引擎 ViewEngines.Engines.Add(new PluginRazorViewEngine()); // 其他初始化代码... }
3. 检查预编译视图的模型引用
在插件项目里,确保视图的模型声明用完全限定名,比如:
@model MySharedModels.UserModel
而不是简写的@model UserModel,避免命名空间冲突导致视图找不到正确的模型类型。
同时检查插件项目的Razor Generator配置(.csproj文件里),确保预编译时没有硬编码主应用的程序集:
<PropertyGroup> <RazorGeneratorEnablePrecompilation>true</RazorGeneratorEnablePrecompilation> <RazorGeneratorNamespace>MyPlugin.Views</RazorGeneratorNamespace> </PropertyGroup>
最后总结
核心就是要让主应用和插件的模型类型是同一个CLR类型,同时确保程序集加载上下文一致,视图引擎能正确解析模型类型的引用。按上面的步骤来,应该能解决你的问题。
内容的提问来源于stack exchange,提问作者Sim
相关产品推荐
相关产品推荐

