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

时间:2010-08-16 07:30:09

标签: asp.net fxcop

由于某些原因,在我们的ASP.NET Web应用程序中,不建议使用Response.Redirect("something", True)。对于endResponse参数,它应与False一起使用。我们希望使用自定义FxCop规则强制执行此操作。 我已经设法找到Response.Redirect的用法,但现在我想找到endResponse参数的值。我怎么能这样做?

我们使用以下代码:

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并认为endResponse参数是幕后的整数,但我不再那么肯定了。无论如何,methodCall.Operands中似乎没有任何布尔值。

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

1 个答案:

答案 0 :(得分:1)

虽然参数类型实际上是System.Boolean,但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));
            }
        }
    }