1

I'm using the mvcsitemapprovider in my ASP.NET MVC 4 project and I wanted to know if it was possible to control whether a navigation link is shown based on whether or not the device viewing the page is a mobile device (basically I only want to support certain areas of my application on a mobile device).

Is this possible? I've done a search for this but didn't find anything so sorry if this is duplicating an existing question.

Nathan Hadley
  • 100
  • 1
  • 10

1 Answers1

1

Use a custom visibility provider.

public class MobileVisibilityProvider : SiteMapNodeVisibilityProviderBase
{
    public bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata)
    {
        // Optional - You can use custom attributes to set different options
        // specific to this visibility provider.
        string visibility = node.Attributes["visibility"];
        if (string.IsNullOrEmpty(visibility))
        {
            return true;
        }
        visibility = visibility.Trim();

        // See the following answer for some advice about how
        // to make this work with the latest browsers
        // http://stackoverflow.com/questions/5233090/how-do-i-detect-a-mobile-browser-in-a-net-mvc3-application
        if (HttpContext.Current.Request.Browser.IsMobileDevice && visibility.ToUpper() == "FALSE")
        {
            return false;
        }

        // If the logic is indeterminate in this visibility provider for 
        // any reason, default to true
        return true;
    }
}

And then you can set the visibility on or off for mobile devices on your nodes by calling up this visibility provider.

XML

<mvcSiteMapNode title="Some Node" controller="Home" action="Contact" visibilityProvider="MyNamespace.MobileVisibilityProvider, MyAssembly" visibility="false" />

.NET Attributes

[MvcSiteMapNode(Title = "Some Node", VisibilityProvider = "MyNamespace.MobileVisibilityProvider, MyAssembly", CustomAttributes = @"{ ""visibility"": ""false"" }")

Note that you can also set the visibility provider SiteMap-wide by using the Default Visibility Provider setting, so you would not need to set the visibilityProvider on every applicable node. But there can only be 1 default visibility provider (with the internal DI container), and setting it to the FilteredSiteMapNodeVisibilityProvider is generally a more flexible option.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212