远程处理示例:在 Internet 信息服务 (IIS) 中承载

下面的示例实现一个具有几点复杂之处的基本 Web 服务。使用 BinaryFormatter 的原因是有效负载更紧凑,因而系统序列化和反序列化流所花费的时间更少。此外,如果 Internet 信息服务 (IIS) 正在使用 Windows 集成身份验证(也称作 NTLM 身份验证),服务器将对客户端进行身份验证,然后将 IIS 能够验证的身份返回到客户端。最后,您还可以采用如下措施来保护 Web 服务的安全:更改客户端配置文件中的 URL 以使用“https”作为协议方案,配置 IIS 以要求对虚拟目录进行安全套接字层 (SSL) 加密(示例中没有说明这一过程)。

警告

.NET Framework 远程处理在默认情况下不进行身份验证或加密。因此,建议您在与客户端或服务器进行远程交互之前,采取任何必要的措施以确认它们的身份。因为 .NET Framework 远程处理应用程序需要 FullTrust 权限才能执行,所以,未经授权的客户端如果被授予访问您服务器的权限,该客户端就可能像完全受信任的客户端一样执行代码。应始终验证终结点的身份并将通信流加密,通过在 IIS 中承载远程类型,或者通过生成自定义信道接收对来完成这项工作。

编译和运行该示例

  1. 将所有文件保存在一个名为 RemoteIIS 的目录中。

  2. 通过在命令提示符处键入以下命令编译整个示例:

    csc /noconfig /t:library /r:System.Web.dll /out:ServiceClass.dll ServiceClass.cs

    csc /noconfig /r:System.Runtime.Remoting.dll /r:System.dll /r:ServiceClass.dll Client.cs

  3. 创建一个 \bin 子目录并将 ServiceClass.dll 复制到该子目录中。

  4. 在 IIS 中创建一个虚拟目录。使虚拟目录的别名为“HttpBinary”,并将源目录设置为“RemoteIIS”目录。

  5. 将此虚拟目录的身份验证方法设置为集成 Windows 验证(即以前的 NTLM 身份验证)。

  6. 确保 IIS 已经启动,然后在“RemoteIIS”目录中的命令提示符处键入 client。

该应用程序可在单台计算机上运行或通过网络运行。如果要在网络上运行该应用程序,必须用远程计算机的名称替换客户端配置中的"localhost"。

ServiceClass.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Web;

public interface IService{

   DateTime GetServerTime();
   string GetServerString();

}

// IService exists to demonstrate the possibility of publishing only the interface.
public class ServiceClass : MarshalByRefObject, IService{

   private int InstanceHash;

   public ServiceClass(){
      InstanceHash = this.GetHashCode();
   }

   public DateTime GetServerTime(){
      return DateTime.Now;
   }

   public string GetServerString(){
      // Use the HttpContext to acquire what IIS thinks the client's identity is.
      string temp = HttpContext.Current.User.Identity.Name;
      if (temp == null || temp.Equals(string.Empty))
         temp = "**unavailable**";
      return "Hi there. You are being served by instance number: " 
         + InstanceHash.ToString() 
         + ". Your alias is: " 
         + temp;
   }
}

Web.config

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown 
               mode="SingleCall" objectUri="SAService.rem"
               type="ServiceClass, ServiceClass"/>
         </service>
         <channels>
            <channel ref="http"/>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>

Client.cs

using System;
using System.Collections;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;

public class Client{

   public static void Main(string[] Args){

         // Tells the system about the remote object and customizes the HttpChannel
         // to use the binary formatter (which understands that base64 encoding is needed).
         RemotingConfiguration.Configure("Client.exe.config");

         // New proxy for the ServiceClass.
         // If you publish only the IService interface, you must use Activator.GetObject.
         ServiceClass service = new ServiceClass(); 
            
         // Programmatically customizes the properties given to the channel. This sample uses the
         // application configuration file.
         // IDictionary Props = ChannelServices.GetChannelSinkProperties(service);
         // Props["credentials"] = CredentialCache.DefaultCredentials;

         // Reports the client identity name.
         Console.WriteLine("ConsoleIdentity: " + WindowsIdentity.GetCurrent().Name);

         // Writes what the server returned.
         Console.WriteLine("The server says : " + service.GetServerString());
         Console.WriteLine("Server time is: " + service.GetServerTime());      
   }
}

Client.exe.config

<configuration>
   <system.runtime.remoting>
      <application>
         <channels>
            <channel ref="http" useDefaultCredentials="true" port="0">
               <clientProviders>
                  <formatter 
                     ref="binary"
                  />
               </clientProviders>
            </channel>
         </channels>
         <client>
            <wellknown 
               url="https://localhost:80/HttpBinary/SAService.rem"
               type="ServiceClass, ServiceClass"
            />
         </client>
      </application>
   </system.runtime.remoting>
</configuration>

请参见

概念

远程应用程序的配置
在 Internet 信息服务 (IIS) 中承载远程对象

其他资源

远程处理示例