Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字符串长度计算不正确_C#_Wcf_String - Fatal编程技术网

C# 字符串长度计算不正确

C# 字符串长度计算不正确,c#,wcf,string,C#,Wcf,String,我的同事和我正在调试他正在处理的WCF服务中的一个问题,其中字符串的长度计算不正确。他正在运行此方法以对其WCF服务中的方法进行单元测试: // Unit test method public void RemoveAppGroupTest() { string addGroup = "TestGroup"; string status = string.Empty; string message = string.Empty; appActiveDirecto

我的同事和我正在调试他正在处理的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");
    }
}
我们试图进入.NET源代码以查看string.IsNullOrEmpty接收到的值,但当我们尝试计算变量时,IDE打印了此消息:“无法获取局部值或参数‘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");
    }
}
我们在这件事上真的很紧张。还有其他人经历过这样的行为吗?关于调试它有什么建议吗


下面是发生行为的
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
以及
字符串.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 
}

编辑:

以下是引发ArgumentNullException时“Watch”窗口中变量的屏幕截图:

另外,第二个屏幕截图显示了检查字符串长度时抛出的异常,在上面5行显式声明该字符串后:

更新#3:我们尝试更改局部变量的名称,它通过了null检查和长度检查,但在调用
string.IsNullOrEmpty
时失败。请参见此屏幕截图:


响应:

  • 我们不使用任何工具来修改MSIL。我们已经执行了清理,还手动删除了构建目录中的所有文件,并强制重新生成…同样的结果

  • 以下语句的计算结果为true并进入if块:
    if(string.IsNullOrEmpty(“AOD”){/**}

  • 构造函数的调用方式如下:

    试试看
    {
    使用(AppActiveDirectoryDomain=new AppActiveDirectoryDomain(AppName,DomainName))
    {
    }
    }

这直接在WCF服务方法本身中;AppName和DomainName是调用的参数。即使绕过这些参数并使用新字符串,我们仍然会得到错误


我有两个建议

  • 使用ILDASM查看正在生成的IL,可能在此处发布IL,以便社区可以查看

  • 例如,将参数“AppName”的名称更改为非常不同的“xxxAppName”


  • 我知道第2点可能看起来毫无意义,但我在过去遇到过似乎无法解释的情况,结果发现没有编译某些内容或存在范围冲突,而调试器显示了您所期望的内容。而且,尝试一下也无妨:)

    这是一个64位问题。或者至少这只是一个运行64位的问题。在64位操作系统上的IIS 7.0中,默认情况下,所有网站都托管在64位进程中。如果我们将服务设置为托管在32位进程中,问题就会消失。

    如果在抛出的异常上放置断点,并将
    AppName
    AppName.Length
    添加到手表中,它们会显示什么?它们会显示“AppName=”AOD“和“AppName.Length==3”-因此它们的计算结果正确。我在问题的底部附上了一个屏幕截图。你可以让测试更加清晰:
    如果(“AOD”.Length==0)抛出…
    。这将排除变量
    AppName
    作为问题的来源。如果仍然抛出异常,您可能对此无能为力。另一个问题:在单元测试方法和抛出的异常之间,调用了
    AppActiveDirectoryDomain
    的构造函数在哪里?你也能展示一下代码吗?5/3:今天我们将尝试在不同的工作站上运行测试。如果我们收到同样的错误,我可能会开始悬赏。否则,我们将假定他安装的VS2008/.NET已损坏。我们尝试为局部变量使用不同的名称,它成功地进行了手动空值检查和长度检查,但在
    string.IsNullOrEmpty
    中失败。查看我发布的第三个截图链接。我发布了IL。我们两人都不觉得可疑,但我们都不是IL专家。@Justin,IL看起来不错。。。您能否将一些消息写入调试窗口(Diagnostics.debug.WriteLine)。我们可以看到调试器看到了什么,但这可能有助于查看执行代码看到了什么。