65.9K
CodeProject 正在变化。 阅读更多。
Home

编辑多个 IIS 站点和服务器上的虚拟目录

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (9投票s)

2006年1月19日

CPOL

5分钟阅读

viewsIcon

48874

downloadIcon

381

一个简单的工具,用于查看和编辑多个网站和 Web 服务器上的虚拟目录设置。

引言

本文是我之前一篇题为《管理多个 IIS 站点和服务器上的虚拟目录》的文章的第二部分。我在那里描述的虚拟目录查看器工具已得到一些新功能的改进。本文将重点介绍这些新功能(仅限于它们),因此,强烈建议您查看第一部分。主要的新功能是使查看器能够以读/写方式访问 IIS 元数据库中托管的虚拟目录数据(不再是有限的只读方式)。因此,查看器实际上变成了一个编辑器,但我们仍然称其为虚拟目录查看器(v2)

虚拟目录查看器 v2 的新功能

虚拟目录查看器(v2)此版本引入的新功能是

  • 能够搜索矩阵中显示的某一组数据中的特定物理路径(或路径的一部分),以查找哪个 Web 服务器上的哪个网站的哪个虚拟目录当前指向该路径;
  • 能够编辑矩阵中的单元格,实际修改该单元格所引用的正确 Web 服务器和 Web 网站上的虚拟目录配置;
  • 能够(即同时添加)将新的虚拟目录定义注入到多个 Web 网站和 Web 服务器中;
  • 能够同时修改多个 Web 网站和 Web 服务器上的虚拟目录定义;
  • 能够同时从多个 Web 网站和 Web 服务器中移除虚拟目录定义。

主窗体上的按钮

下表列出了工具主窗体上的按钮以及相应的功能。对于版本 1 中已有的功能,请参阅本文的第一部分

形状 函数 描述 v2 新增功能
加载数据 从指定的 Web 服务器和 Web 网站检索数据
保存 将当前矩阵保存到文件
Load (加载) 从文件加载矩阵
未使用。 编辑选定的虚拟目录单元格
注入 注入、修改或移除虚拟目录
查找 查找字符串并高亮显示包含该字符串的所有单元格
全选 选择当前矩阵中的所有单元格(以准备复制粘贴操作)
转置 转置当前矩阵,通过交换行和列
应用过滤器 应用过滤条件
网站... 打开“网站选择器”对话框

编辑功能的实现方式

正如引言中所述,此版本的虚拟目录查看器工具与前一个版本的主要区别在于能够编辑矩阵中显示的虚拟目录配置。编辑功能是通过类似如下的代码实现的(请参阅VDirEdit.vb中的 btnOk_Click 事件处理程序),该代码使用了 System.DirectoryServices.DirectoryEntry 类。

Dim de As New DirectoryEntry(VDirMetabasePath)
Dim OldPhysPath As String = de.Properties("Path").Value()
Dim NewPhysPath As String = txtPhysPath.Text
de.Properties("Path")(0) = NewPhysPath
de.CommitChanges()
de.Dispose()

当然,还需要将用户将要编辑的 IIS 元数据库条目的某些信息存储在某处。我决定将这些信息作为附加数据直接与矩阵的每个单元格相关联。为了达到这个目标,我创建了一个名为 VirtualDir 的简单类,它包含了我需要的关于用户将要编辑的虚拟目录的所有信息(我称它们为“元数据”,用于操作每个单独的 DirectoryEntry 实例:Web 服务器、网站、元数据库路径、虚拟目录逻辑名称等),定义如下。

Public Class VirtualDir

  Public VDName As String = ""
  Public VDPhysicalPath As String = ""
  Public VDWebSiteAndServer As String = ""
  Public VDMetabasePath As String = ""

  Public Overrides Function ToString() As String
    Return VDPhysicalPath
  End Function

End Class

这个类然后在创建支持矩阵可视化的 DataSetDataTable 时直接实例化;DataTable 的某些列实际上是 VirtualDir 类型(请参阅VDirViewer.vb中的 btnLoadData_Click 事件处理程序)。

VDirMatrix = New DataTable("VDirMatrix")
Dim col As New DataColumn("VDirName", Type.GetType("System.String"))
VDirMatrix.Columns.Add(col)
...
col = New DataColumn(dr("WebSiteName"), Type.GetType("VDirViewer.VirtualDir"))
col.DefaultValue = New VirtualDir
VDirMatrix.Columns.Add(col)
...

我在 VirtualDir 类中重写的 ToString() 方法确保了当 DataGrid 绑定到基础 DataTable 时,对 DataGrid 在相应单元格中显示的某些内容进行控制。

这样添加在每个单元格后面的“元数据”,当然需要持久化,并在用户单击保存加载按钮时检索。为了完成这项任务,我创建了一个名为 VDirDataSet 的类,用于替代标准的 DataSet 类。VDirDataSet 是一个派生自 System.Data.DataSet 的类,它重载了 WriteXmlReadXml 方法,以实现对自定义 DataSet 列的一种自定义序列化/反序列化(请参阅VDirDataSet.vb中的代码)。反序列化过程(ReadXml 方法)显然能够重新创建包含一些 VirtualDir 类型列的 DataTable(比较VDirViewer.vb中的 btnLoadData_Click 过程和VDirDataSet.vb中的 ReadXml 过程)。

搜索功能的实现方式

搜索功能的目的是提供一种快速的方法来高亮显示矩阵中包含的虚拟目录物理路径与给定搜索字符串匹配的单元格。为了实现这种高亮显示,我决定创建一个 DataGridTextBoxColumn 类的专用版本,该版本能够在搜索字符串在其内容中找到时使用不同的背景色进行自我渲染。因此,我创建的类包含搜索和高亮显示的逻辑(请参阅DataGridColoredTextBoxColumn.vb),而执行查找操作实际上只是创建一个合适的 DataGridTableStyle 并将其应用于显示的 DataGrid

Private Sub cmdFind_Click(ByVal sender As System.Object, _
          ByVal e As System.EventArgs) Handles cmdFind.Click
    If dgMatrix.DataSource Is Nothing Then Exit Sub

    SearchString = InputBox("Enter the string you want to find:", _
                            "Find", SearchString)
    Try
      dgMatrix.TableStyles.RemoveAt(0)
    Catch ex As Exception
    End Try
    dgMatrix.TableStyles.Add(CreateGridStyle((SearchString <> "")))
End Sub


Private Function CreateGridStyle(Optional ByVal Search _
                 As Boolean = True) As DataGridTableStyle

    Dim ColWidth As New NameValueCollection
    ' Preserve column width from preceding TableStyle

    If Not CurrentTableStyle Is Nothing Then
      Dim gcs As DataGridColumnStyle
      For Each gcs In CurrentTableStyle.GridColumnStyles
        ColWidth(gcs.MappingName) = gcs.Width
      Next
    End If

    Dim dt As DataTable = CType(dgMatrix.DataSource, DataView).Table
    Dim GridStyle = New DataGridTableStyle
    GridStyle.MappingName = dt.TableName
    Dim nameColumnStyle As DataGridTextBoxColumn

    Dim dc As DataColumn
    For Each dc In dt.Columns
      If Search Then
        nameColumnStyle = New DataGridColoredTextBoxColumn
      Else
        nameColumnStyle = New DataGridTextBoxColumn
      End If
      nameColumnStyle.MappingName = dc.ColumnName
      nameColumnStyle.HeaderText = dc.ColumnName
      If Not ColWidth(dc.ColumnName) Is Nothing Then
        nameColumnStyle.Width = ColWidth(dc.ColumnName)
      End If
      GridStyle.GridColumnStyles.Add(nameColumnStyle)
    Next
    CurrentTableStyle = GridStyle
    Return GridStyle
End Function

关注点

我认为此实现中最有趣的点是

  • 使用基于自定义类型的 DataTable
  • 修改 DataSet 的序列化/反序列化以支持列中的自定义类型;
  • 使用 DataGridTableStyle 和自定义 DataGridTextBoxColumnDataGrid 中的数据提供个性化渲染。
© . All rights reserved.