使用 Microsoft.Web.Administration (MWA) 访问配置节

作者:Saad Ladki

摘要

本文介绍如何使用 Microsoft.Web.Administration API 以编程方式访问 IIS 配置文件(applicationHost.config 和 web.config)中的配置节。 配置文件可处理包含嵌套元素和集合的复杂节。 下面的几个示例便是使用了 IIS_schema.xml 文件中定义的真实 IIS 配置节。 本文介绍如何使用 Microsoft.Web.Administration 提供的基类以及强类型类来表示这些部分,从而以通用方式访问和操作这些节。

介绍

本文提供了几个示例以说明如何使用 Microsoft.Web.Administration API 以编程方式访问 IIS 配置节。 这将处理具有嵌套元素 (system.webServer/asp) 和集合 (system.webServer/security/isapiCgiRestriction) 的节。 第一部分演示如何使用 Microsoft.Web.Administration 提供的泛型基类来操作这些节,第二部分提供了表示这些节的强类型包装类的使用方式示例。

包含嵌套元素和集合的节的架构

包含嵌套元素的节

system.webServer/asp 节便是一个包含嵌套元素的示例节。 “session”元素在“asp”节中定义。 本节的架构如下所示。 架构和其他嵌套元素中还有其他属性,但示例中未显示这些属性。

<sectionSchema name="system.webServer/asp"> 
  <attribute name="appAllowClientDebug" type="bool" defaultValue="false" /> 
  <attribute name="appAllowDebugging" type="bool" defaultValue="false" /> 
  <!-- Omitted to simplify --> 
  <element name="session"> 
    <attribute name="allowSessionState" type="bool" defaultValue="true" /> 
    <attribute name="keepSessionIdSecure" type="bool" defaultValue="true" /> 
  </element> 
</sectionSchema>

包含集合的节

system.webServer/security/isapiCgiRestriction 节包含元素集合,这些元素按关键字编制索引。 该节的架构如下所示。

<sectionSchema name="system.webServer/security/isapiCgiRestriction"> 
  <collection addElement="add" clearElement="clear" removeElement="remove"> 
    <attribute name="path" type="string" expanded="true" required="true" isUniqueKey="true" validationType="nonEmptyString" /> 
      <attribute name="allowed" type="bool" required="true" defaultValue="false" /> 
      <attribute name="groupId" type="string" required="false" /> 
      <attribute name="description" type="string" /> 
  </collection> 
  <attribute name="notListedIsapisAllowed" type="bool" defaultValue="false" /> 
  <attribute name="notListedCgisAllowed" type="bool" defaultValue="false" /> 
</sectionSchema>

对节的通用访问

Microsoft.Web.Administration 提供了多个泛型基类,这些基类表示配置系统中的不同组件。

  • Configuration:表示单个配置文件(applicationHost.config 或者网站和应用程序的 web.config 文件)
  • ConfigurationElement:用于表示配置文件中的元素的泛型实体。 这是配置节、集合条目、节中嵌套元素等的基类。
  • ConfigurationAttribute:表示 ConfigurationElement 中的属性
  • ConfigurationSection:派生自 ConfigurationElement,表示 IIS 架构文件中定义的部分。 用于访问部分的各种属性。
  • ConfigurationElementCollection:由 ConfigurationElements 组成的集合类。 也派生自 ConfigurationElement。

下面的示例演示如何在 system.webServer/asp 节中访问嵌套元素。

static void Main(string[] args) {  
    ServerManager serverManager = new ServerManager();  
    Configuration config = serverManager.GetApplicationHostConfiguration();  
          ConfigurationSection section = config.GetSection("system.webServer/asp");  
          ConfigurationElement element = section.GetChildElement("session"); 
  Console.Write("allowSessionState attribute value: ");  
          Console.WriteLine(element.GetAttributeValue("allowSessionState"));  
          Console.WriteLine("Set allowSessionState value to false"); 
  element.SetAttributeValue("allowSessionState", false); 
  Console.Write("allowSessionState attribute value: ");  
          Console.WriteLine(element.GetAttributeValue("allowSessionState"));  
  serverManager.CommitChanges();  
    }

ServerManager 类是访问各种服务器设置的入口点。 我们在 applicationHost.config 文件中设置属性,但也可以在各个站点和应用程序的 web.config 文件中访问和更改这些属性。 CommitChanges 调用会保存更改的设置。

下一个示例演示如何循环访问集合中的元素并向其添加元素。

static void Main(string[] args) {         
          ServerManager serverManager = new ServerManager();     
  Configuration config = serverManager.GetApplicationHostConfiguration();         
ConfigurationSection section = 
      config.GetSection("system.webServer/security/isapiCgiRestriction");
    ConfigurationElementCollection collection = section.GetCollection(); 

      // Iterating through the elements in the collection foreach (ConfigurationElement element in collection) 
 { 
  Console.Write("Path: " + element.GetAttributeValue("path")); 
Console.WriteLine(" Allowed: " + element.GetAttributeValue("allowed")); 
        } 
       // Adding a new element to the collection        ConfigurationElement newElement = collection.CreateElement(); 
      newElement.SetAttributeValue("path", @"%SystemDir%\someDll.dll"); 
      newElement.SetAttributeValue("allowed", false); 
      collection.Add(newElement); 
      serverManager.CommitChanges();             
    }

用于访问节的强类型类

可以编写派生自泛型基类的强类型类,从而更加简单、直观地访问属性。 如果必须多次访问同一节以执行不同操作,这特别有用。 这些类还确保你能够在编译时检查属性类型。 利用这些类,可避免了繁琐地调用 GetChildElement 和 GetAttributeValue 等方法。

下面的示例显示了 system.webServer/asp 节的包装器和节的“session”元素。 此代码片段中未包含该节中的所有属性。

public sealed class AspSection : ConfigurationSection { 
   private AspSession _session; 
    public AspSection() 
    { 
    } 

    public AspSession Session 
    {          
        get 
    { 
        if (_session == null) 
         {             
              _session = (AspSession)GetChildElement("session", 
typeof(AspSession)); 
         } 
       return _session; 
    }         
 }         
   } 

    public sealed class AspSession : ConfigurationElement { 
    public AspSession() 
    { 
    } 
     public bool AllowSessionState 
     { 
        get { 
       return (bool)base["allowSessionState"]; 
          } 
         set 
    { 
           base["allowSessionState"] = value; 
         } 
      } 
    }

上面的示例中的 GetChildElement 调用用于访问配置元素(节、集合元素等)中的嵌套元素。 调用 base[...] 会包装 GetAttributeValue 和 SetAttributeValue 类,用于检索和设置这些属性的值。

下一个示例演示如何以强类型方式访问嵌套元素中的属性。

static void Main(string[] args) { 
    ServerManager serverManager = new ServerManager(); 
    Configuration config = serverManager.GetApplicationHostConfiguration(); 
    AspSection section = (AspSection)config.GetSection("system.webServer/asp", 
        typeof(AspSection)); 
    Console.WriteLine(section.Session.AllowSessionState); 
    section.Session.AllowSessionState = false; 
    serverManager.CommitChanges(); 
}

调用 config.GetSection,以获取节路径以及你要创建的节类型。 默认情况下,调用 config.GetSection 会创建 ConfigurationSection,若要获取强类型包装器的实例,需要传入一种类型。

下面的示例说明了如何为具有集合的节创建强类型类。 此示例使用 system.webServer/security/isapiCgiRestriction 节。 此代码片段未包括本节中出现的所有属性。

public sealed class IsapiCgiRestrictionSection : ConfigurationSection {  
    private IsapiCgiRestrictionCollection _collection;             
    public IsapiCgiRestrictionSection() { 
      }         
    public IsapiCgiRestrictionCollection IsapiCgiRestrictions { 
        get { 
          if (_collection == null) { 
            _collection = 
              (IsapiCgiRestrictionCollection)GetCollection(typeof(IsapiCgiRestrictionCollection)); 
          } 
        return _collection; 
        } 
      } 
    }

基类 (ConfigurationElement) 的 GetCollection 方法用于访问该元素的默认集合。

下一个示例显示集合本身的强类型类和集合中的元素。

public sealed class IsapiCgiRestrictionCollection : ConfigurationElementCollectionBase<IsapiCgiRestrictionElement> { 
   public IsapiCgiRestrictionCollection() {  
      } 
   public new IsapiCgiRestrictionElement this[string path] {  
        get { 
          for (int i = 0; i< Count; i++) { 
            IsapiCgiRestrictionElement restriction = base[i]; 
            if (String.Equals=(Environment.ExpandEnvironmentVariables(restriction.Path),  
              Environment.ExpandEnvironmentVariables(path), StringComparison.OrdinalIgnoreCase)) {  
              return restriction; 
            } 
          } 
        return null; 
      } 
    } 
    public IsapiCgiRestrictionElement Add(string path, bool allowed) { 
        IsapiCgiRestrictionElement element = CreateElement(); 
        element.Path = path; 
        element.Allowed = allowed; 
        return Add(element); 
    } 
    protected override IsapiCgiRestrictionElement CreateNewElement(string elementTagName) { 
        return new IsapiCgiRestrictionElement(); 
      } 
    } 
    public sealed class IsapiCgiRestrictionElement : ConfigurationElement { 
  public IsapiCgiRestrictionElement() { 
      } 
     public bool Allowed { 
      get { 
        return (bool)base["allowed"]; 
      } 
      set { 
        base["allowed"] = value; 
      } 
    }         
     public string Path { 
      get { 
        return (string)base["path"]; 
      } 
      set { 
        base["path"] = value; 
      } 
     } 
   }

对于强类型集合类,能够使用集合键(在本例中为“path”属性)为集合编制索引非常有益。 Add 方法的参数采用该元素的必需属性。 在这种情况下,Add 方法只能采用“path”属性,然后“allowed”属性将具有其默认值。

以下示例使用这些强类型类循环访问集合中的条目并向其添加元素。

static void Main(string[] args) { 
  ServerManager serverManager = new ServerManager();             
  Configuration config = serverManager.GetApplicationHostConfiguration(); 
  IsapiCgiRestrictionSection section =  
    (IsapiCgiRestrictionSection)config.GetSection("system.webServer/security/isapiCgiRestriction", typeof(IsapiCgiRestrictionSection));
  // Iterating through the elements in the collection 
  foreach (IsapiCgiRestrictionElement element in section.IsapiCgiRestrictions) { 
    Console.Write("Path: " + element.Path); 
    Console.WriteLine(" Allowed: " + element.Allowed); 
  } 
  // Adding a new element to the collection 
  section.IsapiCgiRestrictions.Add(@"%SystemDir%\someDll.dll", false); 
  serverManager.CommitChanges(); 
}