我的同事和我正在调试他正在处理的WCF服务中的问题,其中字符串的长度未被正确评估.他正在运行此方法来对其WCF服务中的方法进行单元测试:
// 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");
}
}
Run Code Online (Sandbox Code Playgroud)
我们试图进入.NET源代码以查看string.IsNullOrEmpty接收的值,但是当我们尝试评估变量时,IDE打印了此消息:'无法获取本地或参数'值的值,因为此指令不可用指针,可能是因为它已被优化掉了.(所涉及的项目均未启用优化).因此,我们决定在长度检查之前尝试在方法本身内部明确设置变量的值 - 但这没有帮助.
// 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");
}
}
Run Code Online (Sandbox Code Playgroud)
我们真的在这个问题上脱颖而出.有没有其他人经历过这样的行为?有关调试的提示吗?
这是AppActiveDirectoryDomain行为发生的对象的MSIL :
.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
Run Code Online (Sandbox Code Playgroud)
和string.IsNullOrEmpty电话的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
}
Run Code Online (Sandbox Code Playgroud)
编辑:
以下是抛出ArgumentNullException时"Watch"窗口中变量的屏幕截图:http://imgur.com/xQm4J.png
另外,第二个屏幕截图显示了在检查字符串长度时抛出的异常,在明确声明5行之后:http://imgur.com/lSrk9.png
更新#3:我们尝试更改局部变量的名称,并通过空检查和长度检查,但在调用时失败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是调用的参数.即使绕过这些参数并使用新字符串,我们仍然会得到错误.
事实证明这是一个 64 位问题。或者至少它\xe2\x80\x99只是运行64位时的问题。在 64 位操作系统上的 IIS 7.0 中,默认情况下所有网站都托管在 64 位进程中。如果我们将服务设置为托管在 32 位进程中,问题就会消失。
\n| 归档时间: |
|
| 查看次数: |
909 次 |
| 最近记录: |