동료와 저는 문자열 길이가 올바르게 평가되지 않는 곳에서 작업중인 WCF 서비스에서 문제를 디버깅하고 있습니다. 우리가 시도 할 때 우리는 string.IsNullOrEmpty
는 수신 된 어떤 값을 확인하기 위해 .NET 소스 코드를 한 단계하려고문자열 길이가 잘못 계산되었습니다.
// Unit test method
public void RemoveAppGroupTest()
{
string addGroup = "TestGroup";
string status = string.Empty;
string message = string.Empty;
appActiveDirectoryServicesClient.RemoveAppGroup("AOD", addGroup, ref status, ref message);
}
// Inside the WCF service
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public void RemoveAppGroup(string AppName, string GroupName, ref string Status, ref string Message)
{
string accessOnDemandDomain = "MyDomain";
RemoveAppGroupFromDomain(AppName, accessOnDemandDomain, GroupName, ref Status, ref Message);
}
public AppActiveDirectoryDomain(string AppName, string DomainName)
{
if (string.IsNullOrEmpty(AppName))
{
throw new ArgumentNullException("AppName", "You must specify an application name");
}
}
하지만, IDE는이 메시지를 인쇄 : 그는 단위 테스트 자신의 WCF 서비스의 방법이 방법을 실행 '로컬 또는 인수'value '값을이 명령 포인터에서 사용할 수 없으므로 가져올 수 없습니다. 아마도 최적화 된 것이므로 가능합니다.' (관련된 프로젝트 중 어느 것도 최적화가 활성화되어 있지 않습니다.) 그래서 우리는 길이 검사 직전에 메소드 자체의 변수 값을 명시 적으로 설정하기로 결정했습니다.하지만 도움이되지 않았습니다.
// Lets try this again.
public AppActiveDirectoryDomain(string AppName, string DomainName)
{
// Explicitly set the value for testing purposes.
AppName = "AOD";
if (AppName == null)
{
throw new ArgumentNullException("AppName", "You must specify an application name");
}
if (AppName.Length == 0)
{
// This exception gets thrown, even though it obviously isn't a zero length string.
throw new ArgumentNullException("AppName", "You must specify an application name");
}
}
우리는 정말이 머리카락을 내고 있습니다. 다른 사람이 이와 같은 행동을 경험 했습니까? 디버깅에 대한 팁? string.IsNullOrEmpty
호출
.method public hidebysig specialname rtspecialname instance void .ctor(string AppName, string DomainName) cil managed
{
.maxstack 5
.locals init (
[0] class [System]System.Net.NetworkCredential ldapCredentials,
[1] string[] creds,
[2] string userName,
[3] class [mscorlib]System.ArgumentNullException exc,
[4] class [System.DirectoryServices]System.DirectoryServices.ActiveDirectory.DirectoryContext directoryContext,
[5] class [System.DirectoryServices]System.DirectoryServices.ActiveDirectory.Domain domain,
[6] class [System.DirectoryServices.Protocols]System.DirectoryServices.Protocols.LdapException V_6,
[7] class [mscorlib]System.Exception V_7,
[8] bool CS$4$0000,
[9] char[] CS$0$0001,
[10] string[] CS$0$0002)
L_0000: ldarg.0
L_0001: ldsfld string [mscorlib]System.String::Empty
L_0006: stfld string MyNamespace.MyClass.AppActiveDirectoryDomain::appOU
L_000b: ldarg.0
L_000c: call instance void [mscorlib]System.Object::.ctor()
L_0011: nop
L_0012: nop
L_0013: ldstr "AOD"
L_0018: call bool [mscorlib]System.String::IsNullOrEmpty(string)
L_001d: ldc.i4.0
L_001e: ceq
L_0020: stloc.s CS$4$0000
L_0022: ldloc.s CS$4$0000
L_0024: brtrue.s L_0037
L_0026: nop
L_0027: ldstr "AppName"
L_002c: ldstr "You must specify an application name"
L_0031: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string, string)
L_0036: throw
그리고 MSIL :
.method public hidebysig static bool IsNullOrEmpty(string 'value') cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: brfalse.s L_000d
L_0003: ldarg.0
L_0004: callvirt instance int32 System.String::get_Length()
L_0009: ldc.i4.0
L_000a: ceq
L_000c: ret
L_000d: ldc.i4.1
L_000e: ret
}
편집 :
여기에 행동이 발생하는 인 AppActiveDirectoryDomain
객체에 대한 MSIL을의
후 명시 적 선언, 문자열의 길이를 검사 할 때 예외를 나타내는 제 스크린이 발생되고 : 여기
51,515,이 경우 ArgumentNullException가 발생되는 순간의 '시계'창에서 변수의 스크린 샷이다 위의 5 줄 : http://imgur.com/lSrk9.png
업데이트 # 3 : 로컬 변수의 이름을 변경하려고 시도했지만 null 체크와 길이 검사를 통과했지만 string.IsNullOrEmpty
을 호출하면 실패합니다. 이 스크린 샷을 참조하십시오 : http://imgur.com/Z57AA.png.
응답 :이
우리는 MSIL을 수정하는 어떤 도구를 사용하지 마십시오. 우리는 정리를 수행하고 빌드 디렉토리에서 수동으로 모든 파일을 삭제하고 강제로 다시 작성 ... 같은 결과.
다음 문은 true로 평가되고 if 블록 (
if (string.IsNullOrEmpty("AOD")) { /* */ }
)을 입력합니다.는 생성자과 같이 호출된다
try { using (AppActiveDirectoryDomain domain = new AppActiveDirectoryDomain(AppName, DomainName)) { } }
이는 WCF 서비스 방법 자체에 즉시이고; AppName 및 DomainName은 호출에 대한 매개 변수입니다. 이러한 매개 변수를 무시하고 새 문자열을 사용하더라도 오류가 발생합니다.
던져진 예외에 중단 점을 넣고 시계에'AppName'과'AppName.Length'를 추가하면 무엇을 보여줄까요? –
그들은 'AppName == "AOD"와 "AppName.Length == 3"을 보여 주므로 올바르게 평가됩니다. 내 질문의 맨 아래에 스크린 샷을 첨부했습니다. –
테스트를 모호하지 않게 만들 수 있습니다 :'if ("AOD".Length == 0) throw ...'. 그러면 변수의'AppName'이 문제의 출처가 될 수 있습니다. 예외가 계속 던져지면 예외를 수행 할 수 없습니다. – stakx