MVC区域和路由

时间:2010-08-03 18:09:23

标签: asp.net-mvc-2

我希望有一个名为“Products”的区域,我可以使用

等路线
  

http://localhost/products/foo

     

http://localhost/products/bar

我希望将视图和其他资源组织到像

这样的文件夹结构中
/areas/products/views/foo/index.aspx
/areas/products/views/bar/index.aspx

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

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

如果我宣布像

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

并请求网址

  

http://localhost/products/foo

然后调用ProductsController.Index(),正如我所料。但是,由于视图“foo”不在views / products或views / shared文件夹中,因此找不到它。

我该怎么做才能将每​​个产品的页面保存在一个单独的文件夹中?

1 个答案:

答案 0 :(得分:1)

我对你的问题没有具体的答案,因为我不确定我对它的理解。但是我对解决方案的方向有一般的感觉。

当一个人开始更改视图的位置时,找到这些视图的相应方法也需要更改。一种简单的方法是覆盖FindViewFindPartialView方法。

一个简单的演示。我创建了一个名为Blog的区域,一个带有Index方法的Blog控制器。在我的情况下,我将控制器操作用作SubFolder,但我确信这可以扩展到每个产品文件夹的情况。我假设该产品将是一个请求参数。 Area http://www.freeimagehosting.net/uploads/85b5306402.gif

基本思想是查询控制器,区域,操作和id的controllercontext,并修改默认的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);
    }