最近在學習.net core的同時将老師的MVC5項目中的子產品搬過來用,其中有一塊就是利用Attribute來生成菜單。
一·首先定義Action實體
/// <summary>
/// Action
/// </summary>
public class Action
{
/// <summary>
/// ActionId
/// </summary>
[DisplayName("ActionId")]
public Guid Id { get; set; }
/// <summary>
/// 唯一的名稱
/// </summary>
[DisplayName("唯一的名稱")]
public string Name { get; set; }
/// <summary>
/// 分區
/// </summary>
[DisplayName("分區")]
public string AreaName { get; set; }
/// <summary>
/// 控制器
/// </summary>
[DisplayName("控制器")]
public string ControllerName { get; set; }
/// <summary>
/// 活動
/// </summary>
[DisplayName("活動")]
public string ActionName { get; set; }
/// <summary>
/// 參數
/// </summary>
[DisplayName("參數")]
public string Parameter { get; set; }
/// <summary>
/// 文字
/// </summary>
[DisplayName("文字")]
public string Text { get; set; }
/// <summary>
/// 葉節點
/// </summary>
[DisplayName("葉節點")]
public bool IsLeaf { get; set; }
/// <summary>
/// 顯示順序
/// </summary>
[DisplayName("顯示順序")]
public int Ordinal { get; set; }
/// <summary>
/// 是否顯示在左側的導航欄中
/// </summary>
[DisplayName("是否顯示在左側的導航欄中")]
public bool ShowInLeftNavigationBar { get; set; }
/// <summary>
/// 圖示
/// </summary>
[DisplayName("圖示")]
public string IconClass { get; set; }
/// <summary>
/// 級次
/// </summary>
[DisplayName("級次")]
public int Depth { get; set; }
/// <summary>
/// 是否連結
/// </summary>
[DisplayName("是否連結")]
public bool IsLink { get; set; }
/// <summary>
/// 上級名稱(采用上級名稱而非上級Id是為了友善資料的存入)
/// </summary>
[DisplayName("上級名稱")]
public string ParentName { get; set; }
/// <summary>
/// 限制角色
/// </summary>
[DisplayName("限制角色")]
public string AllowedRoles { get; set; }
}
二.建立Attribute類
/// <summary>
/// 方法描述
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class ActionDescriptorAttribute : Attribute
{/// <summary>
/// 方法描述
/// </summary>
/// <param name="name">名稱(必須唯一)</param>
/// <param name="text">标題</param>
/// <param name="depth">深度</param>
/// <param name="ordinal">顯示順序</param>
/// <param name="isLink">是否顯示為連結</param>
/// <param name="showInLeftNavigationBar">是否顯示在左側的導航欄中</param>
public ActionDescriptorAttribute(string name, string text, bool isLink, int depth)
{
this.Name = name;
this.Text = text;
this.IsLink = isLink;
this.Depth = depth;
this.IsLeaf = true;
this.ShowInLeftNavigationBar = true;
this.Ordinal = 0;
}
/// <summary>
/// 名稱(必須唯一)
/// </summary>
public string Name { get; set; }
/// <summary>
/// 顯示的文本
/// </summary>
public string Text { get; set; }
/// <summary>
/// 圖示
/// </summary>
public string IconClass { get; set; }
/// <summary>
/// 參數
/// </summary>
public string Parameter { get; set; }
/// <summary>
/// 是否子菜單
/// </summary>
public bool IsLeaf { get; set; }
/// <summary>
/// 顯示順序
/// </summary>
public int Ordinal { get; set; }
/// <summary>
/// 是否在左邊導航欄顯示
/// </summary>
public bool ShowInLeftNavigationBar { get; set; }
/// <summary>
/// 一級菜單,該值為1,二級菜單,該值為2,依次類推
/// </summary>
public int Depth { get; set; }
/// <summary>
/// 是否連結
/// </summary>
public bool IsLink { get; set; }
/// <summary>
/// 上級名稱
/// </summary>
public string ParentName { get; set; }
}
三.建立ActionsConfig類
public class ActionsConfig
{
/// <summary>
/// 是否生成Actions
/// </summary>
public static bool GenerateConfigs { get; set; }
/// <summary>
/// 是否采用追加模式,如果是追加模式則不删除現有資料
/// </summary>
public static bool IsAppendMode { get; set; }
/// <summary>
/// 是否更新現有記錄
/// </summary>
public static bool IsModifed { get; set; }
public static Task<int> GetActions(string[] namespaces)
{
if (!GenerateConfigs) return new Task<int>(() => 0);
DAL.NoteBookContext db = new DAL.NoteBookContext();
var types = Assembly.GetExecutingAssembly().GetExportedTypes().Where(t => namespaces.Contains(t.Namespace)).ToArray();
var actions = new List<DAL.Entities.Action>();
for (int i = 0; i < types.Length; i++)
{
bool isMvcController = types[i].IsSubclassOf(typeof(Controller));
//bool isApiController = types[i].IsSubclassOf(typeof(ApiController));
//if (!isMvcController && !isApiController) continue;
var fullName = types[i].FullName;
var name = types[i].Name;
var areaName = GetAreaName(fullName);
var tAttr = types[i].GetCustomAttribute<Attributes.ActionDescriptorAttribute>();
var authorize = types[i].GetCustomAttributes<AuthorizeAttribute>();
string roles = "";
if (authorize != null)
roles = string.Join(",", authorize.Select(a => a.Roles));
if (null != tAttr)
{
string attrName = tAttr.Name;
//如果是追加模式需要判斷是否已經存在
bool find = db.Actions.Where(a => a.Name == attrName).Count() > 0;
if (!IsAppendMode || !find)
actions.Add(new DAL.Entities.Action
{
Id = Guid.NewGuid(),
Name = tAttr.Name,
Text = tAttr.Text,
Parameter = tAttr.Parameter,
AreaName = areaName,
ControllerName = name.Substring(0, name.IndexOf("Controller")),
ActionName = "#",
IsLeaf = tAttr.IsLeaf,
IconClass = tAttr.IconClass,
Ordinal = tAttr.Ordinal,
ShowInLeftNavigationBar = true,
Depth = tAttr.Depth,
ParentName = tAttr.ParentName,
IsLink = tAttr.IsLink,
AllowedRoles = roles
});
if (find && IsModifed)
{
DAL.Entities.Action action = db.Actions.Where(a => a.Name == attrName).FirstOrDefault();
action.Text = tAttr.Text;
action.Parameter = tAttr.Parameter;
action.AreaName = areaName;
action.ControllerName = name.Substring(0, name.IndexOf("Controller"));
action.ActionName = "#";
action.IsLeaf = tAttr.IsLeaf;
action.IconClass = tAttr.IconClass;
action.Ordinal = tAttr.Ordinal;
action.ShowInLeftNavigationBar = true;
action.Depth = tAttr.Depth;
action.ParentName = tAttr.ParentName;
action.IsLink = tAttr.IsLink;
action.AllowedRoles = string.IsNullOrEmpty(roles) || roles == "None" ? null : roles;
if (string.IsNullOrEmpty(roles) || roles == "None")
action.AllowedRoles = null;
db.SaveChanges();
}
}
var methods = types[i].GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
for (int j = 0; j < methods.Length; j++)
{
var mAttr = methods[j].GetCustomAttribute<Attributes.ActionDescriptorAttribute>();
if (null != mAttr)
{
string attrName = mAttr.Name;
//如果是追加模式需要判斷是否已經存在
bool find = db.Actions.Where(a => a.Name == attrName).Count() > 0;
if (find && IsModifed)
{
DAL.Entities.Action action = db.Actions.Where(a => a.Name == attrName).FirstOrDefault();
action.Text = mAttr.Text;
action.Parameter = mAttr.Parameter;
action.AreaName = areaName;
action.ControllerName = name.Substring(0, name.IndexOf("Controller"));
action.ActionName = methods[j].Name;
action.IsLeaf = mAttr.IsLeaf;
action.IconClass = mAttr.IconClass;
action.Ordinal = mAttr.Ordinal;
action.ShowInLeftNavigationBar = mAttr.ShowInLeftNavigationBar;
action.Depth = mAttr.Depth;
action.ParentName = mAttr.ParentName;
action.IsLink = mAttr.IsLink;
action.AllowedRoles = string.IsNullOrEmpty(roles) || roles == "None" ? null : roles;
if (string.IsNullOrEmpty(roles) || roles == "None")
action.AllowedRoles = null;
db.SaveChanges();
}
if (find && IsAppendMode) continue;
actions.Add(new DAL.Entities.Action
{
Id = Guid.NewGuid(),
Name = mAttr.Name,
Text = mAttr.Text,
Parameter = mAttr.Parameter,
AreaName = areaName,
ControllerName = name.Substring(0, name.IndexOf("Controller")),
ActionName = methods[j].Name,
IsLeaf = mAttr.IsLeaf,
IconClass = mAttr.IconClass,
Ordinal = mAttr.Ordinal,
ShowInLeftNavigationBar = mAttr.ShowInLeftNavigationBar,
Depth = mAttr.Depth,
ParentName = mAttr.ParentName,
IsLink = mAttr.IsLink,
AllowedRoles = roles
});
}
}
}
var bll = new NoteBookBLL<DAL.Entities.Action>();
if (IsAppendMode)
return bll.AddRangeAsync(actions);
else
return bll.DeleteAsync(a => true).ContinueWith(task =>
{
return bll.AddRangeAsync(actions).Result;
});
}
private static string GetAreaName(string fullName)
{
string[] nameSections = fullName.Split(new char[] { '.' });
var areaIndex = Array.IndexOf(nameSections, "Areas", 0);
string areaName = null;
if (areaIndex > 0)
areaName = nameSections[areaIndex + 1];
return areaName;
}
}
四.在StartUp中調用,項目啟動時執行方法。
public Startup(IConfiguration configuration)
{
Configuration = configuration;
ActionsConfig.GenerateConfigs = true;
//是否采用追加模式
ActionsConfig.IsAppendMode = true;
//是否修改現有記錄
ActionsConfig.IsModifed = true;
ActionsConfig.GetActions(new string[] {
"xxx.Controllers"});
}
五.應用。隻需在控制器上添加Attribute屬性,就可以把相應的控制器加入到Action表中。

結果如圖
萌新菜鳥,水準有限,此代碼借鑒了我的老師的項目中的代碼。歡迎各位大佬,批評指正,不吝賜教。
QQ:1051599574
郵箱:[email protected]
轉載于:https://www.cnblogs.com/zhangjun0204/p/9879993.html