如何使用mvcsitemapprovider呈现特定的Sitemap部分 [英] How to render specific Sitemap section using mvcsitemapprovider

查看:89
本文介绍了如何使用mvcsitemapprovider呈现特定的Sitemap部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我说我有站点地图

<mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" >
        <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="MenuHelper,!*">
            <mvcSiteMapNode title="T1" controller="Home" action="T1" />
            <mvcSiteMapNode title="T2" controller="Home" action="T2"/>
        </mvcSiteMapNode>
        <mvcSiteMapNode title="Help" controller="Help" action="Index">
            <mvcSiteMapNode title="T1" controller="Help" action="T1" />
            <mvcSiteMapNode title="T2" controller="Help" action="T2" />
            <mvcSiteMapNode title="T3" controller="Help" action="T3" />
            <mvcSiteMapNode title="T4" controller="Help" action="T4" />
            <mvcSiteMapNode title="T5" controller="Help" action="T5" />
            <mvcSiteMapNode title="T6" controller="Help" action="T6" />
        </mvcSiteMapNode>
</mvcSiteMapNode>

@Html.MvcSiteMap().Menu()将显示包含以上节点的菜单 但可以说在页脚处,我只想显示站点地图中的特定节点,可以说我想显示节点Help:

@Html.MvcSiteMap().Menu() will display menu contained nodes above But lets say on the footer i want to display only specific node from sitemap, lets say I want to display node Help:

    <ul>
    <li>
    <a href="/help">
    </li>
    <li>
    <a href="/help/t1">T1</a>
    </li>
    <li>
    <a href="/help/t2">T2</a>
    </li>
    //and so on....
    </ul>

我该怎么做?

我猜我可能需要创建一个自定义模板,但是如何将字符串值传递给自定义模板呢?

I am guessing that i might need to create a custom template but how can I pass a string value to custom template?

推荐答案

选项1

执行此操作的一种方法是显式设置起始节点.首先,给起始节点一个明确的密钥:

Option 1

One way to do this is to set the starting node explicitly. First, give the starting node an explicit key:

<mvcSiteMapNode title="Help" controller="Help" action="Index" key="HelpKey">
    <mvcSiteMapNode title="T1" controller="Help" action="T1" />
    <mvcSiteMapNode title="T2" controller="Help" action="T2" />
    <mvcSiteMapNode title="T3" controller="Help" action="T3" />
    <mvcSiteMapNode title="T4" controller="Help" action="T4" />
    <mvcSiteMapNode title="T5" controller="Help" action="T5" />
    <mvcSiteMapNode title="T6" controller="Help" action="T6" />
</mvcSiteMapNode>

并使用菜单重载:

@Html.MvcSiteMap().Menu(Html.MvcSiteMap().SiteMap.FindSiteMapNodeFromKey("HelpKey"), false, false)

但是那样做不会给您太多控制权.

But doing it that way doesn't give you much control.

您还可以使用自定义可见性提供程序.您可以使用sourceMetaData词典将自定义数据传递给可见性提供程序,以便可以为每个菜单实例创建一个单独的名称":

You can also use a custom visibility provider. You can pass custom data to the visibility provider using the sourceMetaData dictionary, so you can create a separate "name" for each menu instance:

@Html.MvcSiteMap().Menu(new { name = "MainMenu" })
@Html.MvcSiteMap().Menu(new { name = "HelpMenu" })

然后,您的自定义可见性提供程序可以使用FilteredSiteMapNodeVisibilityProvider用于自定义名称"属性的相同逻辑:

Then your custom visibility provider can use the same logic the FilteredSiteMapNodeVisibilityProvider uses for your custom "name" property:

/// <summary>
/// Filtered SiteMapNode Visibility Provider for use with named controls.
/// 
/// Rules are parsed left-to-right, first match wins. Asterisk can be used to match any control or any control name. Exclamation mark can be used to negate a match.
/// </summary>
public class CustomFilteredSiteMapNodeVisibilityProvider
    : SiteMapNodeVisibilityProviderBase
{
    #region ISiteMapNodeVisibilityProvider Members

    /// <summary>
    /// Determines whether the node is visible.
    /// </summary>
    /// <param name="node">The node.</param>
    /// <param name="sourceMetadata">The source metadata.</param>
    /// <returns>
    ///     <c>true</c> if the specified node is visible; otherwise, <c>false</c>.
    /// </returns>
    public override bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata)
    {
        // Is a visibility attribute specified?
        string visibility = string.Empty;
        if (node.Attributes.ContainsKey("visibility"))
        {
            visibility = node.Attributes["visibility"].GetType().Equals(typeof(string)) ? node.Attributes["visibility"].ToString() : string.Empty;
        }
        if (string.IsNullOrEmpty(visibility))
        {
            return true;
        }
        visibility = visibility.Trim();

        // Check for the source HtmlHelper
        if (sourceMetadata["HtmlHelper"] == null)
        {
            return true;
        }
        string htmlHelper = sourceMetadata["HtmlHelper"].ToString();
        htmlHelper = htmlHelper.Substring(htmlHelper.LastIndexOf(".") + 1);

        string name = sourceMetadata["name"].ToString();

        // All set. Now parse the visibility variable.
        foreach (string visibilityKeyword in visibility.Split(new[] { ',', ';' }))
        {
            if (visibilityKeyword == htmlHelper || visibilityKeyword == name || visibilityKeyword == "*")
            {
                return true;
            }
            else if (visibilityKeyword == "!" + htmlHelper || visibilityKeyword == "!" + name || visibilityKeyword == "!*")
            {
                return false;
            }
        }

        // Still nothing? Then it's OK!
        return true;
    }

    #endregion
}

然后更新您的配置以使用名称而不是控件类型.

Then update your configuration to use the names instead of the control types.

<mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" >
        <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="MainMenu,!*">
            <mvcSiteMapNode title="T1" controller="Home" action="T1" />
            <mvcSiteMapNode title="T2" controller="Home" action="T2"/>
        </mvcSiteMapNode>
        <mvcSiteMapNode title="Help" controller="Help" action="Index" visibility="HelpMenu,!*">
            <mvcSiteMapNode title="T1" controller="Help" action="T1" />
            <mvcSiteMapNode title="T2" controller="Help" action="T2" />
            <mvcSiteMapNode title="T3" controller="Help" action="T3" />
            <mvcSiteMapNode title="T4" controller="Help" action="T4" />
            <mvcSiteMapNode title="T5" controller="Help" action="T5" />
            <mvcSiteMapNode title="T6" controller="Help" action="T6" />
        </mvcSiteMapNode>
</mvcSiteMapNode>

并且不要忘记在配置中将自定义可见性提供程序设置为默认设置.

And don't forget to set your custom visibility provider as the default in your configuration.

使用内部DI(web.config):

Using internal DI (web.config):

<appSettings>
    <add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MyNamespace.CustomFilteredSiteMapNodeVisibilityProvider, MyAssemblyName"/>
</appSettings>

使用外部DI(在DI模块中-显示Ninject示例):

Using external DI (in DI module - Ninject example shown):

this.Kernel.Bind<ISiteMapNodeVisibilityProviderStrategy>().To<SiteMapNodeVisibilityProviderStrategy>()
    .WithConstructorArgument("defaultProviderName", "MyNamespace.CustomFilteredSiteMapNodeVisibilityProvider, MyAssemblyName");

注意:如果您需要关闭父节点的可见性,但使子节点保持可见,则应使用Menu(),SiteMap()或SiteMapPath()的重载之一,允许您将visibleAffectsDescendants参数设置为false.默认情况下是这样.

Note: If you need to toggle a parent node's visibility off but leave the child nodes visible, you should use one of the overloads of Menu(), SiteMap(), or SiteMapPath() that allow you to set the visibilityAffectsDescendants parameter to false. It is true by default.

这篇关于如何使用mvcsitemapprovider呈现特定的Sitemap部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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