代码之家  ›  专栏  ›  技术社区  ›  Peter Alexandr Nikitin

如何在FxCop的自定义规则中获取传递给方法的参数值?

  •  2
  • Peter Alexandr Nikitin  · 技术社区  · 14 年前

    由于某些原因,在我们ASP.NETweb应用程序,不建议使用 Response.Redirect("something", True) . 对于 endResponse 参数。我们想用一个自定义的FxCop规则来实现这一点。 我设法找到了响应。重定向,但现在我想找出 争论。我该怎么做?

    我们使用以下代码:

    public override ProblemCollection Check(Member member)
    {
        var method = member as Method;
        if (method != null)
        {
            foreach (var instruction in method.Instructions)
            {
                switch (instruction.OpCode)
                {
                    case OpCode.Call:
                    case OpCode.Callvirt:
                    case OpCode.Newobj:
                        var call = (Method) instruction.Value;
                        if (call == null)
                        {
                            break;
                        }
                        if (call.Name.Name != "Redirect")
                        {
                            break;
                        }
                        if (call.Parameters.Count == 1)
                        {
                            //Redirect(url)
                            var resolution = GetResolution();
                            var problem = new Problem(resolution);
                            Problems.Add(problem);
                        }
                        if (call.Parameters.Count == 2)
                        {
                            VisitStatements(call.Body.Statements);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    
        return Problems;
    }
    
    public override void VisitExpression(Expression expression)
    {
        var methodCall = expression as MethodCall;
        if (methodCall == null)
        {
            return;
        }
    
        foreach (var operand in methodCall.Operands)
        {
            if (operand.Type.Name.Name == "Int16" || operand.Type.Name.Name == "Int32" || operand.Type.Name.Name == "Int64")
            {
                var literal = operand as Literal;
                if (literal != null && literal.Value is int)
                {
                    var literalValue = (int)literal.Value;
                    if (literalValue == 1)
                    {
                        var resolution = GetResolution();
                        var problem = new Problem(resolution);
                        Problems.Add(problem);
                    }
                }
            }
        }
    }
    

    Introspector 我想 结束响应 参数在幕后是一个整数,但我不再那么确定了。不管怎么说,这里面好像没有布尔值 methodCall.Operands

    有没有人遇到过类似的情况,需要检查传递给方法的参数的实际值?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Nicole Calinoiu    14 年前

    而参数类型实际上是系统.布尔,FxCop IL解析器将其视为整数。下面是该规则的简化版本(假设您希望非文本endResponse值触发规则冲突):

        public override ProblemCollection Check(Member member)
        {
            Method method = member as Method;
            if (method != null)
            {
                this.Visit(method.Body);
            }
    
            return this.Problems;
        }
    
        public override void VisitMethodCall(MethodCall call)
        {
            base.VisitMethodCall(call);
    
            Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;
            if (targetMethod.DeclaringType.FullName.Equals("System.Web.HttpResponse", StringComparison.Ordinal) &&
                targetMethod.Name.Name.Equals("Redirect", StringComparison.Ordinal))
            {
                bool callIsAcceptable = false;
    
                if (targetMethod.Parameters.Count == 2)
                {
                    Expression endResponseOperand = call.Operands[1];
                    if (endResponseOperand.NodeType == NodeType.Literal)
                    {
                        if ((int)((Literal)endResponseOperand).Value == 1)
                        {
                            callIsAcceptable = true;
                        }
                    }
                }
    
                if (!callIsAcceptable)
                {
                    this.Problems.Add(new Problem(this.GetResolution(), call));
                }
            }
        }