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

如何在单个ASP.NET项目中集成MVC Web应用并共享其视图文件夹

解决ASP.NET主应用共享MVC子应用视图文件夹的问题

以下是几种无需复制视图文件夹,让ASP.NET主应用直接使用MVC子应用视图的可行方案:

方案1:自定义Razor视图引擎,扩展视图搜索路径

通过自定义视图引擎,让主应用的视图搜索范围包含MVC子应用的视图目录,步骤如下:

  1. 在ASP.NET主应用中创建自定义视图引擎类:
public class CustomRazorViewEngine : RazorViewEngine
{
    public CustomRazorViewEngine()
    {
        // 新增MVC子应用的视图搜索路径,替换为你的子应用名称
        var subAppViewPaths = new[]
        {
            "~/../MvcSubApp/Views/{1}/{0}.cshtml",
            "~/../MvcSubApp/Views/Shared/{0}.cshtml",
            "~/../MvcSubApp/Views/{1}/{0}.vbhtml",
            "~/../MvcSubApp/Views/Shared/{0}.vbhtml"
        };

        // 合并原有路径与新增路径
        ViewLocationFormats = ViewLocationFormats.Union(subAppViewPaths).ToArray();
        PartialViewLocationFormats = PartialViewLocationFormats.Union(subAppViewPaths).ToArray();
        MasterLocationFormats = MasterLocationFormats.Union(subAppViewPaths).ToArray();
    }
}
  1. 在主应用的Global.asax.cs的Application_Start方法中注册自定义视图引擎:
protected void Application_Start()
{
    // 移除默认的Razor视图引擎
    ViewEngines.Engines.Remove(ViewEngines.Engines.OfType<RazorViewEngine>().FirstOrDefault());
    // 添加自定义视图引擎
    ViewEngines.Engines.Add(new CustomRazorViewEngine());

    // 其他初始化代码...
}

方案2:将MVC子应用的视图打包为嵌入式资源

把MVC子应用的视图设置为嵌入式资源,然后通过自定义视图引擎读取这些资源:

  1. 在MVC子应用中,选中所有视图文件(.cshtml/.vbhtml),在属性窗口设置生成操作为嵌入式资源。

  2. 在MVC子应用的项目文件(.csproj)中添加配置,确保视图资源的命名规范:

<ItemGroup>
  <EmbeddedResource Include="Views\**\*.cshtml">
    <LogicalName>Views.%(RecursiveDir)%(Filename)%(Extension)</LogicalName>
  </EmbeddedResource>
</ItemGroup>
  1. 在ASP.NET主应用中创建嵌入式视图引擎:
public class EmbeddedViewEngine : RazorViewEngine
{
    private readonly Assembly _subAppAssembly;

    public EmbeddedViewEngine(Assembly subAppAssembly)
    {
        _subAppAssembly = subAppAssembly;
        // 配置嵌入式视图的搜索路径模板
        ViewLocationFormats = new[]
        {
            "Views/{1}/{0}.cshtml",
            "Views/Shared/{0}.cshtml"
        };
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var resourcePath = viewPath.TrimStart('~', '/');
        return new EmbeddedRazorView(controllerContext, resourcePath, masterPath, false, FileExtensions, _subAppAssembly);
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        var resourcePath = partialPath.TrimStart('~', '/');
        return new EmbeddedRazorView(controllerContext, resourcePath, null, false, FileExtensions, _subAppAssembly);
    }

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
    {
        var resourcePath = virtualPath.TrimStart('~', '/');
        return _subAppAssembly.GetManifestResourceInfo(resourcePath) != null;
    }
}

// 自定义嵌入式Razor视图实现
public class EmbeddedRazorView : RazorView
{
    private readonly Assembly _assembly;

    public EmbeddedRazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions, Assembly assembly)
        : base(controllerContext, viewPath, layoutPath, runViewStartPages, viewStartFileExtensions)
    {
        _assembly = assembly;
    }

    protected override IViewFile CreateViewFile(string virtualPath)
    {
        var resourcePath = virtualPath.TrimStart('~', '/');
        var stream = _assembly.GetManifestResourceStream(resourcePath);
        return new EmbeddedViewFile(stream);
    }
}

public class EmbeddedViewFile : IViewFile
{
    private readonly Stream _stream;

    public EmbeddedViewFile(Stream stream)
    {
        _stream = stream;
    }

    public Stream OpenRead() => _stream;
}
  1. 在主应用的Application_Start中注册该引擎:
protected void Application_Start()
{
    var subAppAssembly = Assembly.Load("MvcSubApp"); // 替换为你的MVC子应用程序集名称
    ViewEngines.Engines.Add(new EmbeddedViewEngine(subAppAssembly));

    // 其他初始化代码...
}

方案3:使用虚拟路径提供器映射子应用视图目录

通过自定义VirtualPathProvider,将MVC子应用的物理视图目录映射为主应用的虚拟路径,让主应用直接访问子应用的视图文件:

  1. 在主应用中创建自定义虚拟路径提供器:
public class SubAppViewPathProvider : VirtualPathProvider
{
    private readonly string _subAppViewPhysicalPath;
    private readonly string _virtualPathPrefix = "~/SubAppViews/";

    public SubAppViewPathProvider(string subAppViewPhysicalPath)
    {
        _subAppViewPhysicalPath = subAppViewPhysicalPath;
    }

    public override bool FileExists(string virtualPath)
    {
        if (virtualPath.StartsWith(_virtualPathPrefix, StringComparison.OrdinalIgnoreCase))
        {
            var relativePath = virtualPath.Substring(_virtualPathPrefix.Length);
            var physicalPath = Path.Combine(_subAppViewPhysicalPath, relativePath);
            return File.Exists(physicalPath);
        }
        return base.FileExists(virtualPath);
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        if (virtualPath.StartsWith(_virtualPathPrefix, StringComparison.OrdinalIgnoreCase))
        {
            var relativePath = virtualPath.Substring(_virtualPathPrefix.Length);
            var physicalPath = Path.Combine(_subAppViewPhysicalPath, relativePath);
            return new PhysicalFile(virtualPath, physicalPath);
        }
        return base.GetFile(virtualPath);
    }
}
  1. 在主应用的Application_Start中注册路径提供器,并修改视图引擎的搜索路径:
protected void Application_Start()
{
    // 替换为你的MVC子应用视图文件夹的物理路径
    var subAppViewPath = @"D:\Projects\MvcSubApp\Views";
    HostingEnvironment.RegisterVirtualPathProvider(new SubAppViewPathProvider(subAppViewPath));

    // 修改视图引擎的搜索路径,添加虚拟路径前缀
    var razorEngine = ViewEngines.Engines.OfType<RazorViewEngine>().FirstOrDefault();
    if (razorEngine != null)
    {
        var subAppPaths = new[]
        {
            "~/SubAppViews/{1}/{0}.cshtml",
            "~/SubAppViews/Shared/{0}.cshtml"
        };
        razorEngine.ViewLocationFormats = razorEngine.ViewLocationFormats.Union(subAppPaths).ToArray();
    }

    // 其他初始化代码...
}

内容的提问来源于stack exchange,提问作者Amol

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:15:40