如何指定为 Mvc 控制器创建 Mvc 视图的位置?

发布于 2024-07-17 21:02:02 字数 693 浏览 4 评论 0原文

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

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

不过,我希望在 /Views/Manage/ListManager/ 中创建索引视图和所有后续视图。 我将如何实现这个目标?

编辑:有人指出,这个问题与发布的问题重复此处。 看来我的搜索技巧一开始就失败了。

Important Update
Since the release of MVC 2.0 Preview 1 this feature has been implemented as the part of the actual framework itself in the form of Areas. More details available on Phil Haack's blog here

I have a controller called ListManagerController. This controller contain an ActionResult method called Index(). When I right cick on Index in Visual Studio and select Add View the new view is created in /Views/ListManager/Index.

However I want the Index view and all subsequent views to be created in /Views/Manage/ListManager/. How would I accomplish this?

Edit: It was pointed out that this question is a duplicate of the question posted here. It seems my searching skills failed me initially.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

画尸师 2024-07-24 21:02:02

视图的位置与您正在使用的 ViewFactory 相关联。 据我所知,网络表单视图引擎不支持区域[在您的示例中进行管理]。

Spark 支持此功能并且非常干净,您还可以混合搭配 Web 表单和 Spark 视图,这样您就不需要重新创建您的所有视图。

更新: 看起来 Phil Haack 有一个 博客文章。 他的代码是针对 RC 的,但我认为应该可以很好地针对 ASP.NET MVC RTM 进行编译。

The location of views is tied to the ViewFactory you are using. AFAIK the web forms view engines does not support areas [Manage in your example].

Spark supports this and is very clean, you can also mix and match web forms and spark views so you don't have to recreate all your views.

UPDATE: Looks like Phil Haack has a blog post on how to achieve this. His code is for the RC, but I think that should compile fine against ASP.NET MVC RTM.

风启觞 2024-07-24 21:02:02

我知道您已经接受了答案,但这是我在 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 中将 Application_Start 上的默认 ViewEngine 替换为您的自定义 ViewEngine > :

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" }
 );

I know you already accepted an answer but here's what I came up with while experimenting with the same idea, with the help of Phil Haack's post.

First you need to have your own ViewEngine to look for folders under View folder. Something like this : (You'll notice that it looks a lot like Phil Haack's areas code)

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;
    }
}

Then in your Global.asax replace the default ViewEngine with your custom one, on Application_Start :

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

Now when you are defining routes in Global.asax, you need to set a root value indicating the folder to look for under the View folders like so :

routes.MapRoute(
    "ListManager",
    "ListManager/{action}/{id}",
    new { controller = "ListManager", action = "Index", id = "", root = "Manage" }
 );
疧_╮線 2024-07-24 21:02:02

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

所以我将在这里引用我对该问题的回答。

我想出了一个不同的解决方案
这不需要我自己动手
查看引擎。

基本上,我想将 MVC 保留为
尽可能以“惯例”为驱动,但我
仍然想组织我的所有
~/Views/Admin 下的“管理”视图
文件夹。

示例:

  • ~/Views/Admin/User/
  • ~/Views/Admin/News/
  • ~/Views/Admin/Blog/

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

我有一篇博客文章和示例代码
这里: 在 ASP.Net 中组织您的视图
MVC

This question is VERY much a repeat of this question

so I'll quote my answer to that one here.

I came up with a different solution
that didn't require me to roll my own
view engine.

Basically, I wanted to keep MVC as
"Convention" driven as possible, but I
still wanted to organize all of my
"Admin" views under the ~/Views/Admin
folder.

Example:

  • ~/Views/Admin/User/
  • ~/Views/Admin/News/
  • ~/Views/Admin/Blog/

My solution was to create a new base
class for my specific admin
controllers and "force" the path to
the view for that controller.

I have a blog post and sample code
here: Organize your views in ASP.Net
MVC

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文