You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从未引用程序集动态加载预编译视图致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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:47:46