ASP.Net MVC:如何迭代授权或受限制的控制器和操作名称

时间:2017-07-03 17:14:15

标签: c# asp.net-mvc-4

我想获得控制器和受保护的动作名称,并使用控制器和动作名称填充我的类。

请参阅以下代码

[Authorize]
public class Test1Controller : Controller
{
    public ActionResult Index1()
    {
        return View();
    }

    public ActionResult Index2()
    {
        return View();
    }

    [AllowAnonymous]
    public ActionResult Index3()
    {
        return View();
    }   
}

[AllowAnonymous]
public class Test2Controller : Controller
{
    [Authorize]
    public ActionResult Index1()
    {
        return View();
    }

    [Authorize]
    public ActionResult Index2()
    {
        return View();
    }

    public ActionResult Index3()
    {
        return View();
    }   
}

public class Test3Controller : Controller
{
    public ActionResult Index1()
    {
        return View();
    }

    public ActionResult Index2()
    {
        return View();
    }

    public ActionResult Index3()
    {
        return View();
    }   
}

1) Test1Controller 受到保护,但Index3操作具有匿名访问权限。所以我想以这样的方式迭代,结果我将获得Test1Controller名称和两个没有允许匿名属性的动作名称。

2) Test2Controller 具有匿名属性,但其中两个操作受到保护。所以我想获得Test2Controller名称和它的两个动作名称。

3) Test3Controller 对其任何操作都没有保护,因此当我将在控制器和动作集合中进行迭代时,此控制器名称及其任何动作名称都不会出现。

以下代码为我提供了所有不是我要求的控制器和操作名称

Assembly asm = Assembly.GetExecutingAssembly();

var controlleractionlists = asm.GetTypes()
            .Where(type => typeof(System.Web.Mvc.Controller).IsAssignableFrom(type))
            .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
            .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any())
            .Select(x => new { Controller = x.DeclaringType.Name.Replace("Controller",string.Empty), Action = x.Name, ReturnType = x.ReturnType.Name, Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))) })
            .OrderBy(x => x.Controller).ThenBy(x => x.Action).ToList();

所以请告诉我需要在上面的代码中加入什么样的更改,因此那些控制器名称我将获得至少有一个受保护的操作。

请帮我修改一下代码。感谢

1 个答案:

答案 0 :(得分:0)

//for actions with AuthorizeAttribute
var actions = asm.GetTypes()
            .Where(type => typeof(System.Web.Mvc.Controller).IsAssignableFrom(type))
            .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
            .Where(m => m.GetCustomAttributes(typeof(System.Web.Mvc.AuthorizeAttribute), true).Any())
            .Select(x => new { Controller = x.DeclaringType.Name.Replace("Controller", string.Empty), Action = x.Name, ReturnType = x.ReturnType.Name, Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))) })
            .OrderBy(x => x.Controller).ThenBy(x => x.Action);

//for controllers with AuthorizeAttribute
var controllers = asm.GetTypes()
            .Where(type => typeof(System.Web.Mvc.Controller).IsAssignableFrom(type))
            .Select(type => type.GetTypeInfo())
            .Where(type => type.GetCustomAttributes(typeof(System.Web.Mvc.AuthorizeAttribute), true).Any())
            .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
            .Where(m => !m.GetCustomAttributes(typeof(System.Web.Mvc.AllowAnonymousAttribute), false).Any())
            .Select(x => new { Controller = x.DeclaringType.Name.Replace("Controller", string.Empty), Action = x.Name, ReturnType = x.ReturnType.Name, Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))) })
            .OrderBy(x => x.Controller).ThenBy(x => x.Action);

var controlleractionlists = actions.Concat(controllers).ToList();

如果为操作和控制器级别设置了AuthorizeAttribute,则此操作将在结果中两次,但可以很容易地修复。