2010-08-16 2 views
2

ASP.NET 웹 응용 프로그램에서는 특정 이유로 인해 Response.Redirect("something", True)을 사용하지 않는 것이 좋습니다. endResponse 매개 변수는 False와 함께 사용해야합니다. 사용자 지정 FxCop 규칙을 사용하여이를 적용하려고합니다. Response.Redirect의 사용법을 찾을 수 있었지만 지금은 endResponse 인수의 값을 찾고 싶습니다. 어떻게해야합니까?FxCop의 사용자 지정 규칙에서 메서드에 전달 된 매개 변수의 값을 가져 오는 방법은 무엇입니까?

우리는 다음과 같은 코드를 사용하고 : 나는 Introspector을 사용하고 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); 
       } 
      } 
     } 
    } 
} 

,하지만 난 더 이상 그렇게 확실하지 않다. 어쨌든 methodCall.Operands에는 부울이없는 것 같습니다.

비슷한 상황이 발생했을 때, 메소드에 전달 된 매개 변수의 실제 값을 확인해야하는 사람이 있습니까?

답변

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)); 
      } 
     } 
    } 
+0

감사합니다. 나는 그것이 우리가 원하는 것이기 때문에 .Value == 0으로 바꿨다. 또한, 한 가지 방법으로이 규칙에 두 개의 vioaltions가있는 경우 두 가지 모두 Problems 컬렉션에 추가되지만 FxCop에는 하나만 표시된다는 것을 알았습니다. 그런 다음 첫 번째 위반 사항을 수정하면 새 분석을 수행 할 때 두 번째 위반 사항이 표시됩니다. 그 외에도 작동하며이 코드를 사용할 수 있습니다. 감사. – Peter

+0

FxCop UI 응용 프로그램은 해당 대상별로 위반을 그룹화합니다. 문제 목록에서 메시지를 보면 전체 위반 목록이 표시됩니다. –

+0

이상하게도 테스트 프로젝트에서이 문제가 발생했습니다. 실제 프로젝트에 코드를 넣을 때, 나는 모든 정확한 오류를 얻는다. 어쨌든 모든 도움을 주셔서 감사합니다! – Peter