.NET Remoting 在 IIS 下 - ASP.NET 应用程序作为客户端






4.13/5 (16投票s)
在 IIS 下托管远程组件的最简单方法,使用 ASP.NET 应用程序作为客户端。
引言
我曾看过几篇不错的文章,讲解如何创建 .NET 远程应用程序,但没有一篇使用 ASP.NET 应用程序作为客户端。即便是 MSDN 的示例“在 Internet Information Services (IIS) 中托管”,也使用了控制台应用程序作为客户端。
背景
如果要在互联网上访问远程对象,则必须实现自己的安全措施来验证用户,因为 .NET 远程应用程序需要完全信任权限才能执行。将远程应用程序托管在 IIS 下,可以更轻松地实现安全性,特别是当内网受到防火墙的保护且允许的通信通道是 HTTP 时。
Using the Code
以下是创建服务器应用程序和客户端应用程序的步骤。
服务器对象
- 创建一个新的 VB.NET 或 C# 类库 `IServer`,并将 `Class1.vb` 中的代码替换为以下内容。将项目编译为 `IServer.dll`。
Public Interface IServer Function getServerTime() As DateTime End Interface
- 创建一个新的 VB.NET 或 C# 类库项目,其中包含 `clsServer` 类,该类将实现接口 `IServer` 的 `getServerTime` 函数。
Public Class clsServer Inherits MarshalByRefObject Implements IServer.IServer Public Overridable Function getServerTime() _ As DateTime Implements IServer.IServer.getServerTime Return Now.ToString() End Function End Class
- 我还包含了演示项目中的另一个函数,用于在服务器上创建文件。这将让用户毫无疑问地确信远程对象确实通过透明代理被激活了。请确保您想创建文件的文件夹具有写入权限。
- 将此项目编译为“Server.dll”或任何其他适当的名称。
- 在 IIS 中创建一个新的虚拟目录“Server”,方法是“使用虚拟目录创建向导”或
- 在 `c:\Inetpub\wwwroot` 下创建一个新文件夹,并将其重命名为 `Server`。
- 打开 IIS 管理控制台,查看 `Server` 文件夹的属性。
- 在“应用程序名称”旁点击“创建”按钮,默认情况下,新应用程序的名称将是文件夹的名称。点击“确定”按钮关闭属性窗口。
- 在 Windows 资源管理器中导航到 `Server` 文件夹,并在 `Server` 文件夹下创建一个名为“bin”的子文件夹。
- 将“Server.dll”复制到 `bin` 文件夹中。
- 创建一个新的文本文件,输入以下 XML 代码,并将其保存为“web.config”,而不是 `web.config.txt`(在“另存为”对话框中选择“所有文件”或在保存对话框中将文件名用双引号括起来)。此 XML 代码声明了服务和通道。MSDN 提供了有关我们在此处编写的每个 XML 属性的大量信息。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.runtime.remoting> <application> <service> <wellknown mode="Singleton" type="Server.clsServer, Server" objectUri="server.soap" /> </service> <channels> <channel ref="http" /> <serverProviders> <formatter href="binary" /> </serverProviders> </channels> </application> </system.runtime.remoting> </configuration>
- 我们需要理解的最重要属性是“
type
”。在上面的示例中,其值为“Server.clsServer, Server
”,这实际上就是“RootNamespace.ClassName, Assembly name
”。要找出现有项目的这些值,只需在解决方案资源管理器中右键单击项目名称,然后选择“属性”。`ObjectUri
` 是一个唯一标识该对象的名称,从客户端调用此对象时需要它。我们可以使用其他格式“Server.rem”。 - 我们正在使用的通道是 HTTP,格式化器是二进制。有关替代通道和格式化器,请参考 MSDN。我们在这里需要使用 HTTP,因为我们将服务器对象托管在 IIS 下,并且二进制格式化器比 SOAP 格式化器效率更高。
- 此时,如果您在浏览器地址栏中输入 URL `https:///Server/Server.soap?wsdl`(假设您在本地系统上托管服务器对象,否则请将“localhost”替换为有效的 Web 服务器名称),您应该会看到 XML 输出。此 XML 描述了我们在 IIS 下托管的服务。
- 现在该谈谈客户端了。
ASP.NET 客户端应用程序
- 创建一个新的 ASP.NET Web 应用程序。
- 在调用任何函数之前,我们需要对服务器对象有一个引用。此时,我们有几个选择:您可以实际将 `server.dll` 添加到引用中(尽管我们不打算使用本地对象,这是最省事的方式),使用 `soapsuds.exe` 工具创建代理,或者创建一个接口并引用该接口。Soapsuds 工具的限制是,您需要为程序集中的每个类对象创建一个代理。在 .NET 命令提示符下尝试以下命令,`soapsuds.exe` 应该会为您创建一个“proxy.dll”,您可以添加对该代理对象的引用。但这不适用于封装多个类的程序集。
- 我们还可以使用功能更强大的 `WSDL.exe` 工具来创建代理类源代码,并将其包含在项目中。远程对象可以像本地对象一样被创建。
如果您打开此文件,您将在类构造函数中找到 URL `https:///server/server.soap`。此代理类还将具有其他方法,如 `BegingetServerTime` 和 `EndgetServerTime`,用于进行异步调用。
- 另一个推荐的方法是使用接口,就像我们在本例中做的那样。在客户端 ASP.NET 项目中,添加对 `ISever.dll` 的引用。
- 键入...
Imports System.Runtime.Remoting
... 在页面顶部,以使用 .NET remoting 基础结构。
- 现在,在 `WebForm1` 的 `Page_Load` 事件中键入以下代码。
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim objRemote As IServer.IServer 'Getting transparent proxy objRemote = Activator.GetObject(GetType(IServer.IServer), _ "https:///server/server.soap") 'Executing remote object function Response.Write(objRemote.getServerTime()) End Sub
- 按 F5 执行,您应该会看到时间显示出来。
关注点
您可能会惊讶地发现,到目前为止还没有提到 `Client.exe.config` 或 `Global.aspx` 文件。只有当您想使用“new
”运算符而不是 `Activator.GetObject` 方法时,才需要 `Client.exe.config` 文件。拥有此文件是个好主意,当托管远程对象的服务器经常更改时,您可以通过修改 `client.exe.config` 文件中的 `ObjectUri` 来正常执行代码,而无需重新编译服务器对象。您也可以通过在 `web.config` 的 `appSettings` 标记下指定远程对象的 URL 作为键来实现此目的(我就是这样做的)。这项技术在将项目从开发/测试环境复制到生产环境时非常有用,您所要做的就是修改这些 `config` 文件来更改远程对象的 URL!
另一个需要记住的重要方面是,如果您想在客户端和服务器应用程序之间传递自定义类对象作为参数,这些对象应该在一端序列化,在另一端反序列化。这可以通过实现 `ISerializable` 接口或实现自己的方法将对象转换为字节数组来实现。
参考文献
历史
- 2005 年 3 月 3 日:初始帖子
- 2009 年 8 月 1 日:更新了下载文件