MvcSiteMapProvider ISiteMapBuilder与IDynamicNodeProvider结合 [英] MvcSiteMapProvider ISiteMapBuilder in conjunction with IDynamicNodeProvider

查看:242
本文介绍了MvcSiteMapProvider ISiteMapBuilder与IDynamicNodeProvider结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用MvcSiteMapProvider 4.4.3动态地构建数据库中的地图。我下面的这篇文章:的https://github.com/maartenba/MvcSiteMapProvider/wiki/Multiple-Sitemaps-in-One-Application因为我使用多个站点地图。

I'm using MvcSiteMapProvider 4.4.3 to dynamically build a sitemap from the database. I'm following this article: https://github.com/maartenba/MvcSiteMapProvider/wiki/Multiple-Sitemaps-in-One-Application because I'm using multiple sitemaps.

这工作,这是返回的基本结构:

This works and this is the basic structure which is returned:


  • 首页

    • 新闻

    • 产品

    • 关于


    其中一个节点( /产品)应该被动态填充再次根据不同的数据。因此,对于这个,我需要的 /产品节点上的 IDynamicNodeProvider 的实施? (请纠正我,如果我错了吗?的)

    One of the nodes (/Products) should be dynamically populated again based on different data. So for this I need a IDynamicNodeProvider implementation on the /Productsnode? (please correct me if i'm wrong?)

    无论如何,我认为我需要上面。文档显示的方式来做到这一点的XML和使用控制器的动作属性定义的节点上定义的节点上,但在 ISiteMapBuilder 不是'手动'。所以,如果我设置了 ISiteMapNode 实例 .DynamicNodeProvider 财产似乎并没有得到实例化的... .HasDynamicNodeProvider 属性也返回

    Anyway, I think I do need the above. Documentation shows ways to do this on a node defined in XML and on a node defined using attributes on controller actions, but not 'manually' in a ISiteMapBuilder. So if I set the .DynamicNodeProvider property of the ISiteMapNode instance it doesn't seem to get instantiated... The .HasDynamicNodeProvider property also returns false.

    查看源,我看到 PluginProvider -stuff这是关系到 DynamicNodeProviderStrategy 和你去那里,他们'已经失去了我...

    Looking at the source, i see PluginProvider-stuff which is related to DynamicNodeProviderStrategy and there you go, they've lost me...

    如何创建一个 ISiteMapNode /产品在我的 ISiteMapBuilder ,以便它的后代( /产品/猫 /产品/猫/产品)被动态地从数据库中加载?

    How do I create a ISiteMapNode for "/Products" in my ISiteMapBuilder so that it's descendents (/Products/Cat and /Products/Cat/Product) are dynamically loaded from the database?

    推荐答案

    您可以用ISiteMapBuilder做到这一点,但你可能会更好,而不是实施ISiteMapNodeProvider。究其原因,是因为添加节点Sitemap必须在过程的最后完成后,所有节点都被实例化,以确保每个节点正确映射到父节点(当然除了,根节点这不需要父母)。这是主要的设计更改在4.3.0完成。

    You can do this with ISiteMapBuilder, but you are probably better off instead implementing ISiteMapNodeProvider. The reason is because adding the nodes to the SiteMap must be done at the very end of the process after all nodes have been instantiated to ensure that every node is correctly mapped to a parent node (except of course, the root node which doesn't need a parent). This was the major design change that was done in 4.3.0.

    默认SiteMapBuilder类现在已经建立,以确保

    The default SiteMapBuilder class is now already set up to ensure


    1. 的节点正确映射到它们的父节点

    2. 只有1根节点

    3. 所有节点添加到网站地图

    4. 的游客最后执行后,网站地图是完全建立

    据这么想的意义的,添加多个ISiteMapBuilder实例,因为这使得它可以规避这一重要的逻辑。因此,它是最好的,如果你不执行ISiteMapBuilder,而是实现ISiteMapNodeProvider。

    It dosen't make sense to add more than one ISiteMapBuilder instance because this makes it possible to circumvent this important logic. Therefore, it is best if you do not implement ISiteMapBuilder, but instead implement ISiteMapNodeProvider.

    该SiteMapBuilder类需要一个ISiteMapNodeProvider通过其构造函数的依赖。您可以使用CompositeSiteMapNodeProvider类来处理这个接口,所以你可以添加多个ISiteMapNodeProvider实现,如果需要的多样性。

    The SiteMapBuilder class takes an ISiteMapNodeProvider as a dependency through its constructor. You can use the CompositeSiteMapNodeProvider class to handle multiplicity on this interface so you can add more than one ISiteMapNodeProvider implementation, if needed.

    该ISiteMapNodeProvider界面看起来是这样的:

    The ISiteMapNodeProvider interface looks like this:

    public interface ISiteMapNodeProvider
    {
        IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper);
    }
    

    有仅1方法来实现。此外,许多常见的(但可选的)服务是通过接口自动从SiteMapBuilder类通过ISiteMapNodeHelper注入。

    There is just 1 method to implement. In addition, many of the common (but optional) services are injected through the interface automatically from the SiteMapBuilder class through ISiteMapNodeHelper.

    此类是在比IDynamicNodeProvider一个较低的水平。您正在使用ISiteMapNode直接交互,但随着网站地图类的所有交互由SiteMapBuilder处理。该ISiteMapNode被包裹在一个ISiteMapNodeToParentRelation实例,这只是存在,以确保其父节点密钥可被跟踪,直到它被添加到网站地图对象的时间。

    This class is at a lower level than IDynamicNodeProvider. You are interacting with ISiteMapNode directly, but all interaction with the SiteMap class is handled by SiteMapBuilder. The ISiteMapNode is wrapped in a ISiteMapNodeToParentRelation instance, which is just there to ensure that its parent node key can be tracked until the time it is added to the SiteMap object.

    您应该SiteMapNodeProvider看起来是这样的:

    Your SiteMapNodeProvider should look something like this:

    public class CustomSiteMapNodeProvider
        : ISiteMapNodeProvider
    {
        private readonly string sourceName = "CustomSiteMapNodeProvider";
    
        #region ISiteMapNodeProvider Members
    
        public IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper)
        {
            var result = new List<ISiteMapNodeToParentRelation>();
    
            using (var db = new DatabaseContextClass())
            {
                foreach (var category in db.Categories.ToList())
                {
                    var categoryRelation = this.GetCategoryRelation("Products", category, helper);
                    result.Add(categoryRelation);
    
    
                }
    
                foreach (var product in db.Products.Include("Category"))
                {
                    var productRelation = this.GetProductRelation("Category_" + product.CategoryId, product, helper);
                    result.Add(productRelation);
                }
            }
    
            return result;
        }
    
        #endregion
    
        protected virtual ISiteMapNodeToParentRelation GetCategoryRelation(string parentKey, Category category, ISiteMapNodeHelper helper)
        {
            string key = "Category_" + category.Id;
            var result = helper.CreateNode(key, parentKey, this.sourceName);
            var node = result.Node;
    
            node.Title = category.Name;
    
            // Populate other node properties here
    
            // Important - always set up your routes (including any custom params)
            node.Area = "MyArea"; // Required - set to empty string if not using areas
            node.Controller = "Category"; // Required
            node.Action = "Index"; // Required
            node.RouteValues.Add("id", category.Id.ToString());
    
            return result;
        }
    
        protected virtual ISiteMapNodeToParentRelation GetProductRelation(string parentKey, Product product, ISiteMapNodeHelper helper)
        {
            string key = "Product_" + product.Id;
            var result = helper.CreateNode(key, parentKey, this.sourceName);
            var node = result.Node;
    
            node.Title = product.Name;
    
            // Populate other node properties here
    
            // Important - always set up your routes (including any custom params)
            node.Area = "MyArea"; // Required - set to empty string if not using areas
            node.Controller = "Product"; // Required
            node.Action = "Index"; // Required
            node.RouteValues.Add("id", product.Id.ToString());
            node.RouteValues.Add("categoryId", product.CategoryId.ToString()); // Optional - use if you have a many-to-many relationship.
    
            return result;
        }
    }
    

    上面的例子假设您已经由具有按键为产品,这是所有类别将是儿童等手段增加了一个节点。您当然可以调整这个满足您的需求。

    The above example assumes that you have added a node by other means that has the key set to "Products", which all categories will be children of. You can of course adjust this to meet your needs.

    如果你只有实现这个接口1次,并使用一个数据库连接加载整个地图它通常是最好的。您可以随时重构为多个类,每个处理您的界面单独关注的一侧一个表这一点。但是,通常最好,如果你把所有相关的实体之间的键映射逻辑在一起,使其更易于维护。

    It is typically best if you only implement this interface 1 time and use a single database connection to load the entire SiteMap. You can always refactor this into multiple classes that each handle a single table on your side of the interface to separate concerns. But it is generally best if you put all of the key mapping logic between related entities together to make it easier to maintain.

    有关此接口的实现额外的示例,请参阅 XmlSiteMapNodeProvider 和<一个href=\"https://github.com/maartenba/MvcSiteMapProvider/blob/master/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs\"相对=nofollow> ReflectionSiteMapNodeProvider 。

    For additional examples of implementations of this interface, see XmlSiteMapNodeProvider and ReflectionSiteMapNodeProvider.

    这篇关于MvcSiteMapProvider ISiteMapBuilder与IDynamicNodeProvider结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆