Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以编程方式检索startup.cs中与services.addController一起使用的AspNetCore Mvc筛选器(FilterCollection类型)列表?_C#_Asp.net Mvc_Asp.net Core_Asp.net Mvc Filters - Fatal编程技术网

C# 如何以编程方式检索startup.cs中与services.addController一起使用的AspNetCore Mvc筛选器(FilterCollection类型)列表?

C# 如何以编程方式检索startup.cs中与services.addController一起使用的AspNetCore Mvc筛选器(FilterCollection类型)列表?,c#,asp.net-mvc,asp.net-core,asp.net-mvc-filters,C#,Asp.net Mvc,Asp.net Core,Asp.net Mvc Filters,我有一个用于所有控制器操作的授权筛选器,以保护应用程序的端点(例如CustomAuthorizationFilter:IResourceFilter、IFilterMetadata) 可以在startup.cs中添加此自定义筛选器,如下所示: services.AddControllers(o=> { o、 Filters.Add(); //这里还有其他东西。。。 }); 对于我的用例,我希望100%确保所有API(及其控制器)都使用此过滤器进行保护,换句话说,我希望确保MyApp.API.S

我有一个用于所有控制器操作的授权筛选器,以保护应用程序的端点(例如
CustomAuthorizationFilter:IResourceFilter、IFilterMetadata

可以在
startup.cs
中添加此自定义筛选器,如下所示:

services.AddControllers(o=>
{
o、 Filters.Add();
//这里还有其他东西。。。
});
对于我的用例,我希望100%确保所有API(及其控制器)都使用此过滤器进行保护,换句话说,我希望确保
MyApp.API.Server
.csproj
项目引用在其
startup.cs
类中
CustomAuthorizationFilter

我开始做的是在
MyApp.API.Server
要分析项目配置并检查此筛选器是否存在,请执行以下操作:

公共类安全属性阅读器
{
公共布尔授权筛选器存在()
{
返回false;
}
}
我的问题是我无法找到检索此信息的解决方案

你能用你的想法来挑战我吗:)

谢谢大家!


这就是我的问题,不,我正在用我发现与我的情况更相关的解决方案更新帖子:

想法是创建一个将在构建时执行的Roslyn analyzer,该analyzer将读取startup.cs文件,以检查是否引用了目标“CustomAuthorizationFilter”:

public class FilterAnalyser : DiagnosticAnalyzer
    {
        private const string DiagnosticId = "AnalyserId";
        private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(
           DiagnosticId,
           "title",
           "message format",
           "category",
           DiagnosticSeverity.Error,
           isEnabledByDefault: true);

        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }

        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
            context.EnableConcurrentExecution();
            context.RegisterCodeBlockStartAction<SyntaxKind>(cb =>
            {
                bool filterInvocationFound = false;
                Location errorLocation = null;

                // We only care about method bodies.
                if (cb.OwningSymbol.Kind != SymbolKind.Method)return;

                // We only care about methods with parameters.
                IMethodSymbol method = (IMethodSymbol)cb.OwningSymbol;
                if (method.Parameters.IsEmpty)return;

                // we only care about Startup.cs class
                if (method.ContainingType == null || method.ContainingType.Name != "Startup")return;

                cb.RegisterSyntaxNodeAction(ctx =>
                {
                    if (!(ctx.Node is InvocationExpressionSyntax node)) return;
                    if (!(node.Expression is MemberAccessExpressionSyntax expression)) return;

                    if (expression.Parent.Ancestors().Any(c => c.ToString().Contains("CustomAuthorizationFilter")))
                        filterInvocationFound = true;

                }, SyntaxKind.InvocationExpression);

                cb.RegisterCodeBlockEndAction(ctx =>
                {
                    if (!filterInvocationFound )
                    {
                        var diag = Diagnostic.Create(Rule, method.Locations[0]);
                        ctx.ReportDiagnostic(diag);
                    }
                });
            });
        }
    }
公共类过滤器分析器:诊断分析器
{
private const string DiagnosticId=“AnalyserId”;
专用静态DiagnosticDescriptor规则=新建DiagnosticDescriptor(
诊断的,
“头衔”,
“消息格式”,
“类别”,
诊断严重性。错误,
IsEnabled默认为:true);
公共覆盖ImmutableArray支持的诊断{get{return ImmutableArray.Create(Rule);}
公共覆盖无效初始化(AnalysisContext上下文)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.enableCcurrentExecution();
context.RegisterCodeBlockStartAction(cb=>
{
bool filtering=false;
Location errorLocation=null;
//我们只关心方法体。
if(cb.OwningSymbol.Kind!=SymbolKind.Method)返回;
//我们只关心带参数的方法。
IMethodSymbol method=(IMethodSymbol)cb.OwningSymbol;
if(method.Parameters.IsEmpty)返回;
//我们只关心Startup.cs类
if(method.ContainingType==null | | method.ContainingType.Name!=“Startup”)返回;
cb.RegisterSyntaxNodeAction(ctx=>
{
如果(!(ctx.Node为InvocationExpressionSyntax节点))返回;
如果(!(node.Expression为MemberAccessExpressionSyntax表达式))返回;
if(expression.Parent.祖先().Any(c=>c.ToString().Contains)(“CustomAuthorizationFilter”))
filtering=true;
},SyntaxKind.expression);
cb.RegisterCodeBlockEndAction(ctx=>
{
如果(!找到筛选器)
{
var diag=Diagnostic.Create(规则、方法位置[0]);
报告诊断(diag);
}
});
});
}
}

正如@Kirk Larkin所说,这很有趣。您可以创建一个
CheckAttributesFilter
来检查所有操作,但是一个新的问题是,我们如何确认这个
CheckAttributesFilter
对所有操作都有效

public void OnActionExecuting(ActionExecutingContext context)
    {
        var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        if (controllerActionDescriptor != null)
        {
            var isDefined = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                .Any(a => a.GetType().Equals(typeof(CustomAuthorizationFilter)));
        }
    }

正如@Kirk Larkin所说的,这很有趣。您可以创建一个
CheckAttributesFilter
来检查所有操作,但是一个新的问题是,我们如何确认这个
CheckAttributesFilter
对所有操作都有效

public void OnActionExecuting(ActionExecutingContext context)
    {
        var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        if (controllerActionDescriptor != null)
        {
            var isDefined = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                .Any(a => a.GetType().Equals(typeof(CustomAuthorizationFilter)));
        }
    }

有趣的问题。您将如何确保调用您的
AuthorizationFilterExists
方法?@KirkLarkin我有不同的用例,其中我将在调用例如我的OpenAPI中间件时发送
AuthorizationFilterExists()
(true/false)的结果:
services.AddOpenApi(Configuration,true)然后根据这一点,我将做我想做的。您正在尝试在运行时解决设计时问题。正如@Kirk所说,您将如何检查运行验证的代码是否会运行?如何检查代码是否运行?一种肮脏的方法是初始化其构造函数中属性的静态属性,并在控制器的构造函数中检查该属性(
if(!CustomAuthorizationFilter.IsInitialized){throw…})
),但如果您忘记了在一个控制器中,您就回到了原点。我将创建一个在编译时运行的静态分析器。使用solutionInteresting问题更新post。您将如何确保调用您的
AuthorizationFilterExists
方法?@KirkLarkin我有不同的用例,其中我将在调用例如我的OpenAPI中间件时发送
AuthorizationFilterExists()
(true/false)的结果:
services.AddOpenApi(Configuration,true)然后根据这一点,我将做我想做的。您正在尝试在运行时解决设计时问题。正如@Kirk所说,您将如何检查运行验证的代码是否会运行?如何检查代码是否运行?一种肮脏的方法是初始化构造函数中属性的静态属性,并在控件中检查该属性