Question

I am experimenting with security-trimmed action links in ASP.NET MVC, and am considering using the SecurityTrimmedActionLink helper method described here (with some modifications).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using System.Web.Routing;
using System.Web.Mvc;
using System.Collections;
using System.Reflection;
namespace System.Web.Mvc.Html
{
    public static class HtmlHelperExtensions
    {
        public static string SecurityTrimmedActionLink(
        this HtmlHelper htmlHelper,
        string linkText,
        string action,
        string controller)
        {
            return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, false);
        }
        public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, bool showDisabled)
        {
            if (IsAccessibleToUser(action, controller))
            {
                return htmlHelper.ActionLink(linkText, action, controller);
            }
            else
            {
                return showDisabled ? String.Format("<span>{0}</span>", linkText) : "";
            }
        }
        public static bool IsAccessibleToUser(string actionAuthorize, string controllerAuthorize)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            GetControllerType(controllerAuthorize);
            Type controllerType = GetControllerType(controllerAuthorize);
            var controller = (IController)Activator.CreateInstance(controllerType);
            ArrayList controllerAttributes = new ArrayList(controller.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true));
            ArrayList actionAttributes = new ArrayList();
            MethodInfo[] methods = controller.GetType().GetMethods();
            foreach (MethodInfo method in methods)
            {
                object[] attributes = method.GetCustomAttributes(typeof(ActionNameAttribute), true);
                if ((attributes.Length == 0 && method.Name == actionAuthorize) || (attributes.Length > 0 && ((ActionNameAttribute)attributes[0]).Name == actionAuthorize))
                {
                    actionAttributes.AddRange(method.GetCustomAttributes(typeof(AuthorizeAttribute), true));
                }
            }
            if (controllerAttributes.Count == 0 && actionAttributes.Count == 0)
                return true;

            IPrincipal principal = HttpContext.Current.User;
            string roles = "";
            string users = "";
            if (controllerAttributes.Count > 0)
            {
                AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute;
                roles += attribute.Roles;
                users += attribute.Users;
            }
            if (actionAttributes.Count > 0)
            {
                AuthorizeAttribute attribute = actionAttributes[0] as AuthorizeAttribute;
                roles += attribute.Roles;
                users += attribute.Users;
            }

            if (string.IsNullOrEmpty(roles) && string.IsNullOrEmpty(users) && principal.Identity.IsAuthenticated)
                return true;

            string[] roleArray = roles.Split(',');
            string[] usersArray = users.Split(',');
            foreach (string role in roleArray)
            {
                if (role == "*" || principal.IsInRole(role))
                    return true;
            }
            foreach (string user in usersArray)
            {
                if (user == "*" && (principal.Identity.Name == user))
                    return true;
            }
            return false;
        }

        public static Type GetControllerType(string controllerName)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            foreach (Type type in assembly.GetTypes())
            {
                if (type.BaseType.Name == "Controller" && (type.Name.ToUpper() == (controllerName.ToUpper() + "Controller".ToUpper())))
                {
                    return type;
                }
            }
            return null;
        }
    }
}

What I would like to do is put a vertical bar between each link like this:

link1 | link2 | link3

But I don't want two vertical bars to appear between links if a link has been trimmed off (the helper method will return an empty string), and there can't be any vertical bars at all if no links or only one link appears. The SecurityTrimmedActionLink helper method cannot assist with the vertical bars; it will have no knowledge of the other links.

Can this be achieved with some simple logic in the view?

Was it helpful?

Solution

After giving it some thought, I created a new HtmlHelper method:

using System.Text;

namespace System.Web.Mvc.Html
{
    public static class HtmlHelpers
    {
        public static string Delimit(
             this HtmlHelper h, string delimiter, params string[] s)
        {
            bool flag = false;
            StringBuilder b = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
                if (s[i].Length > 0)
                    if (flag)
                        b.Append(delimiter + s[i]);
                    else
                    {
                        flag = true;
                        b.Append(s[i]);
                    }
            return b.ToString();
        }
    }
}

Which should allow me to write:

<% =Html.Delimit("|", 
        Html.SecurityTrimmedActionLink(...),
        Html.SecurityTrimmedActionLink(...),
        ...
    ); 
$>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top