0

重要更新
自 MVC 2.0 Preview 1 发布以来,此功能已作为实际框架本身的一部分以区域的形式实现。Phil Haack 的博客上提供了更多详细信息

我有一个名为 ListManagerController 的控制器。此控制器包含一个名为 Index() 的 ActionResult 方法。当我在 Visual Studio 中右键单击索引并选择添加视图时,新视图将在 /Views/ListManager/Index 中创建。

但是,我希望在 /Views/ Manage /ListManager/ 中创建索引视图和所有后续视图。我将如何做到这一点?

编辑:有人指出,这个问题与此处发布的问题重复。看来我的搜索技巧最初让我失望了。

4

3 回答 3

3

视图的位置与您正在使用的 ViewFactory 相关联。AFAIK Web 表单视图引擎不支持区域 [在您的示例中管理]。

Spark支持这一点并且非常干净,您还可以混合和匹配 Web 表单和 Spark 视图,因此您不必重新创建所有视图。

更新:看起来 Phil Haack 有一篇关于如何实现这一目标的博客文章。他的代码是针对 RC 的,但我认为应该可以针对 ASP.NET MVC RTM 进行编译。

于 2009-05-02T00:34:03.470 回答
1

我知道您已经接受了答案,但这是我在Phil Haack 的帖子的帮助下尝试相同想法时得出的结论。

首先,您需要拥有自己的 ViewEngine 来查找 View 文件夹下的文件夹。像这样:(你会注意到它看起来很像 Phil Haack 的区号)

public class TestViewEngine : WebFormViewEngine
{
    public TestViewEngine()
        : base()
    {
        MasterLocationFormats = new[] {
            "~/Views/{1}/{0}.master",
            "~/Views/Shared/{0}.master"
        };

        ViewLocationFormats = new[] {
            "~/{0}.aspx",
            "~/{0}.ascx",
            "~/Views/{1}/{0}.aspx",
            "~/Views/{1}/{0}.ascx",
            "~/Views/Shared/{0}.aspx",
            "~/Views/Shared/{0}.ascx"
        };

        PartialViewLocationFormats = ViewLocationFormats;
    }
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        ViewEngineResult rootResult = null;

        //if the route data has a root value defined when mapping routes in global.asax
        if (controllerContext.RouteData.Values.ContainsKey("root")) {
            //then try to find the view in the folder name defined in that route
            string rootViewName = FormatViewName(controllerContext, viewName);
            rootResult = base.FindView(controllerContext, rootViewName, masterName, useCache);
            if (rootResult != null && rootResult.View != null) {
                return rootResult;
            }
            //same if it's a shared view
            string sharedRootViewName = FormatSharedViewName(controllerContext, viewName);
            rootResult = base.FindView(controllerContext, sharedRootViewName, masterName, useCache);
            if (rootResult != null && rootResult.View != null) {
                return rootResult;
            }
        }
        //if not let the base handle it
        return base.FindView(controllerContext, viewName, masterName, useCache);
    }

    private static string FormatViewName(ControllerContext controllerContext, string viewName) {
        string controllerName = controllerContext.RouteData.GetRequiredString("controller");

        string root = controllerContext.RouteData.Values["root"].ToString();
        return "Views/" + root + "/" + controllerName + "/" + viewName;
    }

    private static string FormatSharedViewName(ControllerContext controllerContext, string viewName) {
        string root = controllerContext.RouteData.Values["root"].ToString();
        return "Views/" + root + "/Shared/" + viewName;
    }
}

然后在您Global.asax用您的自定义 ViewEngine 替换默认 ViewEngine 时,在Application_Start

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new TestViewEngine());

现在,当您在中定义路由时Global.asax,您需要设置一个root值,指示要在 View 文件夹下查找的文件夹,如下所示:

routes.MapRoute(
    "ListManager",
    "ListManager/{action}/{id}",
    new { controller = "ListManager", action = "Index", id = "", root = "Manage" }
 );
于 2009-05-02T14:56:51.260 回答
0

这个问题非常重复这个问题

所以我会在这里引用我对此的回答。

我想出了一个不同的解决方案,它不需要我滚动自己的视图引擎。

基本上,我想让 MVC 尽可能保持“约定”驱动,但我仍然想在 ~/Views/Admin 文件夹下组织我的所有“管理员”视图。

例子:

  • ~/视图/管理员/用户/
  • 〜/视图/管理/新闻/
  • ~/视图/管理员/博客/

我的解决方案是为我的特定管理控制器创建一个新的基类,并“强制”该控制器的视图路径。

我在这里有一篇博文和示例代码:Organize your views in ASP.Net MVC

于 2009-05-02T05:18:53.067 回答