我正在嘗試開發一種通用功能,可以讓我獲得應用程式的所有操作和所有控制器。我將希望通過所有僅 GET 而不是 POST 的操作來過濾這些控制器操作。換句話說,我希望在應用程式中擁有所有可能的路線。我正在使用反射來做到這一點,但還沒有真正通過。我想使用反射,所以每次添加任何新的控制器和動作時,它們也都在這個串列中。
所以,我想要這個的原因是,我想基本上根據用戶的角色、宣告和/或任何其他用戶權限將這些操作顯示為用戶的動態選單。這應該只向他們展示允許的內容。
非常感謝這方面的任何線索。
謝謝你。
[Table("Menus")]
public class Menu
{
public int ID { get; set; }
public string Name { get; set; }
public string CssClass { get; set; }
public int SortOrder { get; set; }
public MenuLevel MenuLevel { get; set; }
public List<MenuItem> MenuItems { get; set; }
}
[Table("MenuItems")]
public class MenuItem
{
public int ID { get; set; }
public string Name { get; set; }
public string CssClass { get; set; }
public int SortOrder { get; set; }
}
private async Task<List<Menu>> GetAndSaveAllControllerActions()
{
List<Menu> menus = new();
// loop through all potential controller types
foreach (var controllerType in Assembly.GetExecutingAssembly().GetExportedTypes().Where(t => typeof(ControllerBase).IsAssignableFrom(t)))
{
Menu menu = new()
{
Title = controllerType.Name,
MenuLevel = MenuLevel.Level1,
SortOrder = 1,
RouteAddress = @$"\{controllerType.Name}\"
};
menu.Title = menu.Title.Replace("Controller", "");
// get their all public instance methods (excluding inherited ones)
// these are the so-called action methods
foreach (var actionMethod in controllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
{
// get attributes assigned with the method
var attributes = actionMethod.GetCustomAttributes(false);
// filter methods marked with [NonAction]
// filter out the ones with ref or out params too here if
// you have such things
if (!attributes.Any(i => i is NonActionAttribute))
{
// filter POSTs out as you wish
if (!attributes.Any(i => i is HttpPostAttribute))
{
// you can compose something from various info available at this point e.g.
// through 'controllerType', 'actionMethod' or other attributes if they
// exists in 'attributes' (e.g. RouteAttribute)
menu.MenuItems.Add(new MenuItem()
{
MenuID = menu.MenuID,
Title = actionMethod.Name,
RouteAddress = menu.RouteAddress $"{actionMethod.Name}"
});
}
}
}
menus.Add(menu);
}
await CheckForDatabaseExistence(menus);
return menus;
}
private Task<int> CheckForDatabaseExistence(List<Menu> menus)
{
var dbMenus = _context.Menus.ToList();
foreach (var menu in menus)
if (!dbMenus.Contains(menu))
{
_context.Menus.Add(menu);
return _context.SaveChangesAsync();
}
return Task.FromResult(0);
}
我已經修改了代碼,以便將來可以幫助任何人。 感謝 cly 在下面的回答有所幫助。
uj5u.com熱心網友回復:
正如您所提到的,我確信通過 MVC 的路由還有另一種方法可以完成此任務。但是您正在以基于反射的方式開始您的代碼,因此最好繼續使用這種方法而不是混合方法。
在 MVC 中,動作方法可以是Controller基于類的任何方法,其中:
- 是
public - 不是
static - 沒有棘手的引數,例如標有
ref和的引數out - 未標記
[NonAction]屬性
下面的 PoC 代碼向您展示了如何使用這些約束來收集您需要的資料。
(代碼的實作是TestMethod因為測驗執行提供了一個非常方便的快速微執行環境,可以在您的開發域的所有東西都可用時臨時嘗試一些東西。如果您想要的東西被嘗試過,這個假的“測驗”可以簡單地丟棄然后你繼續前進。)
[TestMethod]
public void MyTestMethod()
{
// loop through all potential controller types
foreach (var controllerType in Assembly
.GetExecutingAssembly()
.GetExportedTypes()
.Where(t => typeof(ControllerBase).IsAssignableFrom(t)))
{
// get their all public instance methods (excluding inherited ones)
// these are the so-called action methods
foreach(var actionMethod in controllerType.GetMethods(
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.DeclaredOnly))
{
// get attributes assigned with the method
var attributes = actionMethod.GetCustomAttributes(false);
// filter methods marked with [NonAction]
// filter out the ones with ref or out params too here if
// you have such things
if (!attributes.Any(i=>i is System.Web.Http.NonActionAttribute))
{
// filter POSTs out as you wish
if (!attributes.Any(i => i is System.Web.Http.HttpPostAttribute))
{
// you can compose something from various info available at this point e.g.
// through 'controllerType', 'actionMethod' or other attributes if they
// exists in 'attributes' (e.g. RouteAttribute)
var controllerName = controllerType.Name;
var actionName = actionMethod.Name;
}
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/431766.html
標籤:C# asp.net 核心 .net-core asp.net-core-mvc
上一篇:HTTPS在Caprover中托管的ASP.NETCore應用程式中不起作用
下一篇:C#簡化空檢查條件
