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

ASP.NET MVC 5如何从视图子文件夹中加载视图?

ASP.NET MVC加载多层子文件夹视图的解决方案

这不全是路由问题,但需要配合调整路由逻辑;必须自定义RazorViewEngine才能搞定多层子文件夹视图的加载——默认MVC的视图搜索规则不支持这种场景,而路由的默认解析逻辑也没法把多层路径映射成视图路径的一部分。

一、自定义视图引擎扩展搜索路径

默认的RazorViewEngine只会搜索~/Views/{controller}/{action}.cshtml这类固定结构的文件,要让它支持任意层级的子文件夹,直接扩展它的搜索格式即可:

public class CustomRazorViewEngine : RazorViewEngine
{
    public CustomRazorViewEngine()
    {
        // 添加支持多层子路径的搜索规则
        var extraViewPaths = new[]
        {
            "~/Views/{controller}/{*path}/{action}.cshtml",
            "~/Views/Shared/{*path}/{action}.cshtml"
        };

        // 合并原有规则,保证默认视图的优先级不变
        ViewLocationFormats = ViewLocationFormats.Union(extraViewPaths).ToArray();
        PartialViewLocationFormats = PartialViewLocationFormats.Union(extraViewPaths).ToArray();
    }
}

然后在Application_Start里替换掉默认的视图引擎:

protected void Application_Start()
{
    // 移除默认的Razor引擎
    var defaultEngine = ViewEngines.Engines.OfType<RazorViewEngine>().First();
    ViewEngines.Engines.Remove(defaultEngine);
    // 注册自定义视图引擎
    ViewEngines.Engines.Add(new CustomRazorViewEngine());

    // 其他初始化代码保持不变
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

二、调整路由或改进HandleUnknownAction

仅修改视图引擎还不够,默认路由会把Student/About/Index里的About识别为actionName、Index识别为参数,无法正确映射到视图路径。这里提供两种解决方案:

方案1:修改路由捕获完整路径

在RouteConfig中添加专门针对Student和Employee控制器的路由,捕获控制器后的完整路径:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // 优先处理Student/Employee的多层路径请求
        routes.MapRoute(
            name: "CmsViews",
            url: "{controller}/{*viewPath}",
            defaults: new { action = "LoadCmsView" },
            constraints: new { controller = "^(Student|Employee)$" }
        );

        // 保留默认路由
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

然后在Student和Employee控制器中添加LoadCmsView方法,解析路径并加载视图:

public ActionResult LoadCmsView(string viewPath)
{
    // 空路径默认返回Index视图
    if (string.IsNullOrWhiteSpace(viewPath))
        return View("Index");

    // 直接用捕获到的完整路径查找视图
    var viewResult = View(viewPath);

    // 视图不存在则返回404页面
    if (!viewResult.ViewExists)
        return View("PageNotFound");

    return viewResult;
}

方案2:改进HandleUnknownAction解析请求路径

如果不想修改路由,可直接重写控制器的HandleUnknownAction方法,从请求URL中提取完整视图路径:

protected override void HandleUnknownAction(string actionName)
{
    // 移除控制器路径部分,获取剩余的视图路径
    var viewPath = Request.Url.AbsolutePath.Replace($"/{ControllerContext.RouteData.Values["controller"]}/", "");

    // 尝试加载视图
    var viewResult = View(viewPath);
    if (viewResult.ViewExists)
    {
        viewResult.ExecuteResult(ControllerContext);
        return;
    }

    // 视图不存在时返回404页面
    View("PageNotFound").ExecuteResult(ControllerContext);
}

三、验证效果

现在无论是Student/About/Index还是Student/About/Subfolder1/Subfolder2/Applying这类多层路径,自定义视图引擎都能精准定位对应的.cshtml文件;视图不存在时会自动跳转到PageNotFound页面,完全符合ASP.NET MVC的设计逻辑,无需手动处理文件存在性判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:18:21