How to visually separate security-trimmed action links in ASP.NET MVC
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.Ba开发者_如何学JAVAseType.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?
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(...),
...
);
$>
精彩评论