客户端应用程序调用 Web 服务时收到 System.IO.FileNotFoundException 错误

本文可帮助你解决 ASP.NET Web 应用程序调用 Web 服务时发生的问题 System.IO.FileNotFoundException

原始产品版本: ASP.NET
原始 KB 数: 823196

现象

在 ASP.NET Web 应用程序中调用 Web 服务时,可能会收到以下错误:

System.IO.FileNotFoundException

原因

如果以下条件之一为 true,可能会收到错误:

  • 工作进程无权读取到进程临时目录,而工作进程无权写入进程临时目录。

    注意

    XmlSerializer 类可动态生成并编译代码,以执行序列化和反序列化。 XmlSerializer 使用代码文档对象模型 (CodeDom) 执行编译。 CodeDom 编译使用磁盘上的临时文件。 如果工作进程对 Temp 目录没有读取权限,并且对 Temp 目录具有写入权限,则对 Web 服务的所有调用都会失败。 因此,工作进程需要对 Temp 目录的读取权限和临时目录的写入权限。

  • 生成的代码 XmlSerializer 中存在编译错误。

解决方法 1:向 Temp 目录中的工作进程帐户分配权限

若要解决此问题,如果应用程序部署在 Internet Information Services (IIS) 6.0 上,ASP.NET 工作进程帐户(ASPNET 帐户或网络服务帐户)必须在 Temp 目录中具有读取访问权限和写入访问权限。

注意

如果使用模拟,模拟用户必须对 Temp 目录具有完全访问权限。

若要向 Temp 目录中的工作进程帐户分配所需的权限,请执行以下步骤:

  1. 在 Windows 资源管理器中,找到 .%windir%\temp directory

  2. 右键单击 %windir%\temp,然后选择“ 属性”。

  3. “属性” 窗口中,选择“ 安全 ”选项卡。

  4. 选择“ 添加”,键入 ServerName\ASPNET,然后选择“ 确定”。

    注意

    将 ServerName 替换为 Web 服务器的名称。

    如果将应用程序部署到 IIS 6.0 上,请将 ASPNET 替换为网络服务

  5. 在“允许”,选中“完全控制”复选框,然后选择“确定”。

解决方法 2:在 XmlSerializer 生成的代码中查找编译器错误

若要查找编译器生成的错误,必须将开关添加到 Web.config 文件以保留编译器生成的文件。 为此,请按照下列步骤进行操作:

  1. 文本编辑器(如记事本)中打开 Web.config 文件。

  2. XmlSerialization.Compilation将开关添加到<system.diagnostics>代码部分,如下所示:

    <configuration>
        <system.diagnostics>
            <switches>
                <add name="XmlSerialization.Compilation" value="4"/>
            </switches>
        </system.diagnostics>
    </configuration>
    
  3. 运行客户端应用程序。

    客户端应用程序调用 Web 服务。

  4. %windir%\temp验证目录是否具有_tmpname.00.cs文件和 _tmpname.out 文件。

    _tmpname.00.cs文件是生成的源。 _tmpname.out 文件应具有编译器错误。

    注意

    启用读取权限,并启用对工作进程帐户(ASPNETNETWORK SERVICE)的写入权限,以在 Temp 目录中写入 %tmpname% 文件。

Status

此行为是特意这样设计的。

重现行为的步骤

以下部分提供有关重现行为的步骤的信息。

创建 Web 服务

  1. 启动 Visual Studio .NET。

  2. 使用 Visual C# .NET 或 Visual Basic .NET 创建新的 ASP.NET Web 服务项目。

    默认情况下, 将创建 Service1.asmx

  3. 将项目 命名为 WebServiceTemp

  4. 在解决方案资源管理器中,右键单击 Service1.asmx,然后选择“查看代码”。

  5. Service1.asmx.cs 文件中(如果使用 Visual Basic .NET,则 Service1.asmx.vb 文件),取消注释默认 HelloWorld() Web 方法。

  6. 在“生成”菜单上,选择“生成解决方案” 。

创建客户端应用程序

  1. 使用 Visual C# .NET 或 Visual Basic .NET 创建新的 ASP.NET Web 应用程序。

  2. 将项目 命名为 WebAppTemp

  3. 在解决方案资源管理器中,右键单击“引用”,然后选择“添加 Web 引用”。

  4. “地址”文本框中,键入 WebServiceTemp 的以下 URL
    http://localhost/WebServiceTemp/Service1.asmx

  5. 选择“转到”,然后选择“添加引用”。

  6. 双击 WebForm1 打开 Page_Load 事件代码。

  7. 将以下代码追加到 Page_Load 事件处理程序。

    • Visual C# .NET 示例代码

      // Start an instance of the Web service client-side proxy.
      localhost.Service1 myProxy = new localhost.Service1();
      Response.Write( myProxy.HelloWorld());
      
    • Visual Basic .NET 示例代码

      'Start an instance of the Web service client-side proxy.
      Dim myProxy As localhost.Service1 = New localhost.Service1()
      Response.Write(myProxy.HelloWorld())
      
  8. 在“生成”菜单上,选择“生成解决方案” 。

设置 Temp 目录的权限

若要向 Temp 目录中的工作进程帐户分配所需的权限,请执行以下步骤:

  1. 在 Windows 资源管理器中,找到目录 %windir%

  2. 右键单击 %windir%\temp,然后选择“ 属性”。

  3. “属性” 窗口中,选择“ 安全 ”选项卡。

  4. 选择“ 添加”,键入 ServerName\ASPNET,然后选择“ 确定”。

  5. 请确保“允许”下未选中“写入”复选框,然后选择“确定”。

  6. 运行 Web 应用程序。

    你可能会收到本文的 “症状 ”部分中提到的错误。