在我的ASP.NET MVC应用程序中,我使用一个小助手来遍历所有控制器.这个帮助器位于与我的MVC应用程序不同的程序集中,我正在引用它.
问题是,当在helper中调用Assembly.GetCallingAssembly()方法时,它不会返回MVC app程序集,而是返回帮助程序集.这不是我期望得到的,因为我的所有控制器都存在于MVC app程序集中,我需要反映它.
视图代码(MVC app assembly):
<nav>
<ul id="menu">
@foreach(var item in new MvcHelper().GetControllerNames())
{
@Html.ActionMenuItem(
(string)HttpContext.GetGlobalResourceObject("StringsResourse", item), "Index",
item)
}
</ul>
</nav>
Run Code Online (Sandbox Code Playgroud)
帮助程序代码(独立程序集):
public class MvcHelper
{
public List<string> GetControllerNames()
{
var controllerNames = new List<string>();
GetSubClasses<Controller>().ForEach(
type => controllerNames.Add(type.Name));
return controllerNames;
}
private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
我的路线设置如下:
context.MapRoute(
name: "Area",
url: "Area/{controller}/{action}",
defaults: new
{
controller = "Home",
action = "Dashboard"
}
);
context.MapRoute(
name: "AccountArea",
url: "Area/{accountFriendlyId}/{controller}/{action}",
defaults: new
{
controller = "Home",
action = "Dashboard",
accountFriendlyId = RouteParameter.Optional
}
);
context.MapRoute(
name: "AccountCampaignArea",
url: "Area/{accountFriendlyId}/{campaignFriendlyId}/{controller}/{action}",
defaults: new
{
controller = "Home",
action = "Dashboard",
accountFriendlyId = RouteParameter.Optional,
campaignFriendlyId = RouteParameter.Optional
}
);
Run Code Online (Sandbox Code Playgroud)
而且我强烈希望Area/friendlyAccountName/Home
带我去,Dashboard()
但这不起作用(404).我认为原因是我们去寻找一个friendlyAccountName控制器.
知道如果我应该选择在我的一个控制器之后命名一个帐户,一切都崩溃了,有没有办法在字符串找不到相应的控制器的情况下进入下一个路径?有没有办法在每次修改控制器列表时使用反射并避免维护约束?
编辑
你知道一种不使用反射或至少包含派生类型搜索的方法吗?当第二个路径参数与控制器名称匹配时,我不喜欢产生两次开销的想法(传递约束然后在构造控制器时再次搜索).我希望有一种方法可以在构建控制器然后备份并进入下一个路径时捕获异常.
我需要将所有已注册为列表的区域及其所有控制器作为子列表以及相同的操作。像这样:
AdminArea
HomeController
Index
Add
...
OtherController
...
AnotherArea
HomeController
Index
...
...
Run Code Online (Sandbox Code Playgroud)
我已经检查的回答这个问题,而这一个,但他们不是我要找的。第一个返回所有已注册的路由,第二个一次返回所有控制器。
更新
好的,使用下面的代码我可以获得所有区域,并且通过第二个问题的答案我可以获得所有控制器,但我无法弄清楚每个控制器属于哪个区域。
var areaNames = RouteTable.Routes.OfType<Route>()
.Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
.Select(r => r.DataTokens["area"]).ToList()
.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud) 我有一个控制器名称列表,然后将列出给定控制器中的所有操作(名称,GUID).
此处找到的所有控制器列表.
我还在阅读列出控制器上具有特定属性的所有操作,这些属性与我的目的相匹配,因为我还需要具有特定属性的操作.但我只有所选控制器的名称/ GUID,而不是对象本身.
我的场景:用户选择一个控制器(级联下拉列表),然后选择来自该控制器的操作来配置一些访问(和链接).因此,我只需要具有自定义属性的操作.