代码之家  ›  专栏  ›  技术社区  ›  3Dave

MVC区域和路由

  •  0
  • 3Dave  · 技术社区  · 14 年前

    我想要一个叫“产品”的地方,在那里我可以使用诸如

    http://localhost/products/foo

    http://localhost/products/bar

    我希望将视图和其他资产组织成文件夹结构,如

    /areas/products/views/foo/index.aspx
    /areas/products/views/bar/index.aspx
    

    我想在各自的/区域/产品/视图/(foo bar)/文件夹中保留与每个产品(foo,bar)相关的图像等。

    我也不想为每个产品添加控制器操作。

    如果我宣布一条路线

    context.MapRoute(
        "products-show-product"
        , "Products/{id}"
        , new { controller = "Products", action = "Index", id=UrlParameter.Optional }
        );
    

    并请求URL

    http://localhost/products/foo

    然后 ProductsController.Index() 如我所料,被称为。但是,由于视图“foo”不在视图/产品或视图/共享文件夹中,因此找不到它。

    我该如何做才能将每个产品的页面保存在单独的文件夹中?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Ahmad    14 年前

    我对你的问题没有具体的答案,因为我不确定我对它的理解。不过,我对解决方案的方向有一个大致的看法。

    当一个人开始改变视图的位置时,找到这些视图的相应方法也需要改变。一个简单的方法是重写 FindView FindPartialView 方法。

    一个简单的演示。我创建了一个名为blog的区域,一个带有索引方法的blog控制器。在我的案例中,我使用控制器操作作为子文件夹,但我确信这可以扩展到每个产品文件夹的案例中。我假设产品是一个请求参数。 Area http://www.freeimagehosting.net/uploads/85b5306402.gif

    基本思想是询问ControllerContext中的控制器、区域、操作和ID,并修改默认的ViewEngine查找的内容。区域视图的默认位置如下 "~/Areas/{2}/Views/{1}/{0}.aspx" ,因此我们基本上可以为视图名称注入值,在本例中 ActionName/Index . 视图位置最终将是 ~/Area/Blog/Views/Blog/Index/Index.aspx .

    这只是一个可以使用的代码的大致轮廓。字符串比较绝对可以更新为更健壮的方法。按照目前的情况,这种方法将按预期适用于整个应用程序,但在请求对博客区域执行索引操作时除外。

    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            if (controllerContext.RouteData.DataTokens ["Area"] == "Blog" )
            {
                if (String.Compare(controllerContext.RouteData.Values ["Action"].ToString(),"Index",true) == 0)
                {
                    var viewLocation = String.Format("{0}/{1}", controllerContext.RouteData.Values["Action"].ToString(), viewName);
                    return base.FindView(controllerContext, viewLocation , masterName, useCache);
                }
            }
                return base.FindView(controllerContext, viewName, masterName, useCache);
        }