MVC3导航和面包屑 - 数据驱动

时间:2012-02-03 22:21:16

标签: asp.net-mvc-3 hierarchical-data breadcrumbs mvcsitemapprovider nested-routes

我看过一些关于导航和面包屑的帖子,但没有发现exaxt同样的问题。但是,如果有,请原谅并指出我。谢谢。

我的情况:

Interests                   Profiles
|                       |
|_Interest Area 1               |-Profile Area 1
|   |                       |
|   |_Interest Area 1.1             |_List of Books
|       |                       |
|       |_List of Books                 |_Book Detail
|           |
|           |_Book Detail
|_Interest Area 2
    |
    |_List of Books
        |
        |_Book Detail

层次结构存储在数据库中。入口点兴趣和个人资料是固定的。从那里我不知道孩子会是什么。

当没有孩子离开时,将根据最后选择的(子)类别的值检索书籍。

我有两个问题: 1st:创建合适的路线。我想要的方式是:

/books/{id}/{interestareaname}/{subinterestareaname}/{books}/{page}

其中,为用户友好的网址添加了interestareaname,并且只要您在层次结构中继续,就会不断重复。输出将是: /书籍/ 1 /项目管理/ PRINCE2 /书籍/ 1 这显示了分页列表页面1上的prince2书籍。

但是当只有一个级别时,路线只包含一个兴趣区域,因此成为:

/book/{id}/{interestareaname}/{books}/{page}

我为解决问题1做了什么:

    routes.MapRoute(
        "Details",
        "view/details/{id}/{booktitle}",
        new { controller = "book", action = "Details", id = "*", booktitle= "*"});

    routes.MapRoute(
        "interests",
        "books/{id}/{level1}/{level2}/{level3}/{page}",
        new { controller = "book", action = "books", level1 = "*", level2 = "*", level3 = "*", id = "0", page = UrlParameter.Optional }
    );
    routes.MapRoute(
        "profiles",
        "books/{id}/{level1}/{level2}/{level3}/{page}",
        new { controller = "book", action = "books", level1 = "*", level2 = "*", level3 = "*", id = "0", page = UrlParameter.Optional }
    );

我通过声明应该设置最大级别来达到此目的。那只是因为我不知道如何让它变得更有活力。

现在的问题是区分兴趣类别和个人资料类别。我通过创建相同的路线,但使用不同的名称并在站点地图创建中添加了路径名称来实现这一点。

我遇到的第二个问题是站点地图和面包屑。 我使用MVCsitemapprovider和DynamicNodes功能。

使用站点地图,我在显示详细信息页面时遇到问题。因为书籍既会出现在个人资料中,也会出现在兴趣上。有些书籍会出现在多个兴趣领域或个人档案中。 在每种情况下,我都希望看到我用来获得该书的路径。

首先,我将每本书的详细信息页面添加到站点地图中,但这很疯狂。并创建重复的条目,站点地图不能很好地处理。 其他选项是通过查询字符串将列表页面上的routedata传递给详细信息页面,但这看起来很糟糕,然后我要添加逻辑来解析查询字符串以模仿面包屑,这将很难,因为我只有ID然后最低级别。

我现在花了很多个夜晚,但我仍然无法理解。如果有人可以帮助或指出我正确的方向,我将非常感激。

1 个答案:

答案 0 :(得分:0)

我迄今为止找到的唯一解决方案是实际创建所有可能的路线,例如:

        routes.MapRoute(
            "interest",
            "interest",
            new { controller = "books", action = "viainterest"},
            new { controller = "books", action = "viainterest" }
        );

        routes.MapRoute(
            "interest_1_details",
            "interest/{level1}/view/{id}/{booktitle}",
            new { controller = "books", action = "detailsviainterest_1, level1 = "*", id = 0, booktitle = "*" },
            new { controller = "books", action = "detailsviainterest_1" }
        );

        routes.MapRoute(
                       "interest2details",
                       "interest/{level1}/{level2}/view/{id}/{booktitle}",
                       new { controller = "books", action = "detailsviainterest_2", level1 = "*", level2 = "*", id = 0, booktitle = "*" },
                       new { controller = "books", action = "detailsviainterest_2" }
                   );


        routes.MapRoute(
                        "interestlevel_1",
                        "interest/{id}/{level1}",
                        new { controller = "books", action = "viainterestlevel_1, level1 = "*", id = 0 },
                        new { controller = "books", action = "viainterestlevel_1"}
                    );

        routes.MapRoute(
                       "interestlevel_2",
                       "interest/{id}/{level1}/{level2}",
                       new { controller = "books", action = "viainterestlevel_2", level1 = "*", level2 = "*", id = 0 },
                       new { controller = "books", action = "viainterestlevel_2}
                   );
        //and so on for level 3 and for profiles etc.

在DynamicNodeManager中,我按层次结构添加所有类别,并添加所有项目。现在我得到了一个体面的痕迹,一直到详细页面。由于每个详细信息页面的路径(路由数据和操作)不同,即使是出现在多个类别中的书籍也会显示正确的面包屑。

这解决了我的问题,但我仍然认为应该有更好的方法。当前解决方案的问题在于,由于添加到nodecollection的详细项目,树将变得庞大。另一个缺点是树在应用程序启动时生成。因此,在重置Web应用程序之前,添加新书不会创建节点。

所以,如果有其他建议,我很高兴看到他们。现在我可以继续阅读内容了,最后一切都是这样。