先建两个实体类,用于存储反射来的结果:
/// <summary>
/// 反射控制器实体
/// </summary>
public class ReflectMenuModel
{
/// <summary>
/// 菜单名称,通过反射Desction属性获得
/// </summary>
public string MenuName { set; get; }
/// <summary>
/// 控制器名称
/// </summary>
public string MenuController { set; get; }
/// <summary>
/// 菜单链接
/// </summary>
public string MenuLink { set; get; }
/// <summary>
/// 菜单权限明细
/// </summary>
public List<ReflectMenuActionModel> MenuMx { set; get; }
}
public class ReflectMenuActionModel
{
/// <summary>
/// 动作名称,读自定义属性的值
/// </summary>
public string ActionName { set; get; }
/// <summary>
/// 动作对应的权限ID
/// </summary>
public int ActionId { set; get; }
/// <summary>
/// 访问动作所需权限
/// </summary>
public string ActionAuthor { set; get; }
/// <summary>
/// Action
/// </summary>
public string ActionCode { set; get; }
}
自定义标签类
public class DescriperAttribute:Attribute
{
/// <summary>
/// 名称
/// </summary>
public string Name { set; get; }
/// <summary>
/// 操作权限码0:查看;1:新增;2:修改;3:删除;4:审批;5:导出;6:同步;7:打印
/// </summary>
public int Nid { set; get; }
/// <summary>
/// 逗号隔开的权限码数字
/// </summary>
public string QxItem { set; get; }
/// <summary>
/// 枚举的时候,是否列在其中
/// </summary>
public bool IsFilter { set; get; }
}
控制器代码结构:
[Description("流程管理")]
public class LcglController : BaseController
{
// GET: sysadmin/Lcgl
[Descriper(Name="查看",Nid=0)]
public ActionResult Index()
{
return View();
}
[Descriper(Name="新建",Nid=1)]
public ActionResult Create()
{
return View();
}
[Descriper(Name="编辑",Nid=2)]
public ActionResult Edit()
{
return View();
}
[Descriper(Name="保存",Nid=0,IsFilter=true,QxItem="1,2"]
public JsonResult Save()
{
return MyJson(Rm);
}
}
反射方法:
/// <summary>
/// 反射后台所有控制器和下面的公开action
/// </summary>
/// <returns></returns>
public static List<ReflectMenuModel> GetALLMenuByReflection()
{
List<ReflectMenuModel> controls = new List<ReflectMenuModel>();
var asm = System.Reflection.Assembly.GetExecutingAssembly();
System.Collections.Generic.List<Type> typeList = new List<Type>();
var types = asm.GetTypes();
foreach (Type type in types)
{
string s = type.FullName.ToLower();
if (s.Contains(".sysadmin.") && s.Contains("maincontroller"))
{
continue;//过滤掉后台首页
}
if (s.Contains(".sysadmin.") && s.EndsWith("controller"))
typeList.Add(type);
}
typeList.Sort(delegate(Type type1, Type type2) { return type1.FullName.CompareTo(type2.FullName); });
foreach (Type type in typeList)
{
ReflectMenuModel rm = new ReflectMenuModel();
rm.MenuMx = new List<ReflectMenuActionModel>();
//Response.Write(type.Name.Replace("Controller","") + "<br/>\n");
System.Reflection.MemberInfo[] members = type.FindMembers(System.Reflection.MemberTypes.Method,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic | //【位屏蔽】
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly,
Type.FilterName, "*");
string controller = type.Name.Replace("Controller", "");
//反射Description属性,作为菜单名称
object[] descriptionList = type.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (descriptionList != null && descriptionList.Length > 0)
{
foreach (var dm in descriptionList)
{
DescriptionAttribute da = dm as DescriptionAttribute;
rm.MenuName = da.Description;
break;
}
}
else
{
rm.MenuName = controller;
}
rm.MenuController = controller;
string url = "/sysadmin/" + controller + "/";
rm.MenuLink = url;
foreach (var m in members)
{
if (m.DeclaringType.Attributes.HasFlag(System.Reflection.TypeAttributes.Public) != true)
continue;
ReflectMenuActionModel rma = new ReflectMenuActionModel();
string action = m.Name;
rma.ActionCode = action;
if (action.Contains("<") || action.Contains(">")) continue;
bool isNeedAdd = true;
反射系统自己带的其它属性
//System.Reflection.TypeAttributes attrs = m.DeclaringType.Attributes;
//反射自定义属性DescriperAttribute,过滤不需要的
object[] deserlist = m.GetCustomAttributes(typeof(DescriperAttribute), false);
if (deserlist != null && deserlist.Length > 0)
{
foreach (var cm in deserlist)
{
DescriperAttribute da = cm as DescriperAttribute;
if (da.IsFilter)
{
isNeedAdd = false;
break;
}
rma.ActionAuthor = da.QxItem;
rma.ActionId = da.Nid;
rma.ActionName = da.Name;
break;
}
}
if (!isNeedAdd)
{
continue;
}
if (rma.ActionName == null)
{
rma.ActionName = action;
}
var om = controls.FirstOrDefault(pm => pm.MenuLink == url);
if (om == null)
{
rm.MenuMx.Add(rma);
controls.Add(rm);
}
else
{
var som = om.MenuMx.FirstOrDefault(pm => pm.ActionCode == action);
if (som == null)
{
rm.MenuMx.Add(rma);
}
}
}
}
return controls;
}