简体   繁体   English

在WebForms应用程序中读取自定义配置文件

[英]Reading custom config file in WebForms app

I have classes to read in a custom config file, which work in my (sandbox) MVC app, and in a console app. 我有自定义配置文件的类,可以在我的(沙盒)MVC应用程序和控制台应用程序中使用。 However, it fails to read anything except the top level section when it's run from the web forms app that actually needs it. 但是,当它从实际需要它的Web表单应用程序运行时,它无法读取除顶级部分之外的任何内容。 They all target framework .Net 4.5. 它们都以框架.Net 4.5为目标。 The custom config is a 'carrier' section that contains a list of carriers, each of which has their own settings. 自定义配置是一个“运营商”部分,其中包含运营商列表,每个运营商都有自己的设置。 The web.config extracts: web.config提取:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="CarrierSection" type="SmallWFApp.CarrierSection"/>
    </configSections>

The custom config section file: 自定义配置部分文件:

<?xml version="1.0"?>
<CarrierSection>
  <carriers>
    <carrier name="ups" default-code="UPS0041" >
      <pickupreq value="N"/>
      <limits>
        <limit name="non-doc" weight="200" length="270" width="165" height="165" square="330" />
        <limit name="doc" weight="2.5"  length="0" width="0" height="0" square="0" />
        <limit name="consignment" max-eu="200" max-world="0"/>
      </limits>
      <services>
        <service name="document" caption="DOCUMENT EXPRESS" code="D" live="Y"/>
        <service name="parcel" caption="EXPRESS" code="N" live="Y" />
        <service name = "road" caption="ECONOMY ROAD" code="P" live="N" />
      </services>
    </carrier>
    <carrier name="dhl" default-code="DHL0014" >
      <pickupreq value="Y"/>
      <limits >
        <limit name="non-doc" weight="200" length="270" width="165" height="165" square="330"  />
        <limit name="doc"  weight="2.5"  length="0" width="0" height="0" square="0"/>
      </limits>
      <services>
        <service name="9am" caption="NEXT DAY 9AM"  code="9" />
        <service name = "noon" caption="NEXT DAY 12NOON"  code="2" />
      </services>
    </carrier>
  </carriers>
</CarrierSection>

The c# config section classes that (I think) provide the strong typing: c#config部分类(我认为)提供了强类型:

using System;
using System.Configuration;

namespace SmallWFApp
{
public class CarrierSection : ConfigurationSection
{
    [ConfigurationProperty("carriers")]
    public CarrierElementCollection Carriers
    {
        get { return this["carriers"] as CarrierElementCollection; }
    }
}

//-----------------------------------------

public class CarrierElementCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new CarrierElement();
    }
    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((CarrierElement)element).Name;
    }
    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }
    protected override string ElementName
    {
        get { return "carrier"; }
    }
    public CarrierElement this[int index]
    {
        get { return (CarrierElement)BaseGet(index); }
        set
        {
            if (BaseGet(index) != null)
            {
                BaseRemoveAt(index);
            }
            BaseAdd(index, value);
        }
    }
    new public CarrierElement this[string employeeID]
    {
        get { return (CarrierElement)BaseGet(employeeID); }
    }
    public bool ContainsKey(string key)
    {
        bool result = false;
        object[] keys = BaseGetAllKeys();
        foreach (object obj in keys)
        {
            if ((string)obj == key)
            {
                result = true;
                break;
            }
        }
        return result;
    }
}

//-----------------------------------------------------------------
public class CarrierElement : ConfigurationElement
{
    [ConfigurationProperty("name", DefaultValue = "Other", IsRequired = true, IsKey = true)]
     public string Name
    {
        get { return this["name"] as string; }
        set  { this["name"] = value;  }
    }


    [ConfigurationProperty("default-code", IsRequired = true)]
    public string DefaultCode
    {
        get  { return this["default-code"] as string;  }
        set  {  this["default-code"] = value;  }
    }

    [ConfigurationProperty("pickupreq")]
    public ReqPickupConfigElement ReqPickup
    {
        get  {  return base["pickupreq"] as ReqPickupConfigElement;  }
    }


    [ConfigurationProperty("limits")]
    public LimitElementCollection Limits
    {
        get  { return this["limits"] as LimitElementCollection; }
    }

    [ConfigurationProperty("services")]
    public ServiceElementCollection Services
    {
        get  { return this["services"] as ServiceElementCollection;  }
    }
}


//--------------------------------------------

public class ReqPickupConfigElement : System.Configuration.ConfigurationElement
{
    [ConfigurationProperty("value", DefaultValue = "N")]
    [StringValidator(MinLength = 1, MaxLength = 1)]

    public string Value
    {
        get   {  return base["value"] as string;  }
    }
}

The code in the code-behind-aspx.cs class that reads it: 代码隐藏的aspx.cs类中的代码读取它:

try
{
    CarrierSection config =
                        (CarrierSection)System.Configuration.ConfigurationManager.GetSection(
                        "CarrierSection");

    if (config != null)
    {
        foreach (CarrierElement app in config.Carriers)
        {
            //... (never comes in here) ...
        }

        //lbConfigread.Text = found.ToString();
    }
}
catch (Exception ex)
{
    //...
}

The c# configuration collection/elements to read the 'limits' for each carrier: 用于读取每个运营商的“限制”的c#配置集合/元素:

namespace SmallWFApp
{
    public class LimitElementCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new LimitElement();
        }
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((LimitElement)element).Name;
        }
        public override ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.BasicMap; }
        }
        protected override string ElementName
        {
            get { return "limit"; }
        }
        public LimitElement this[int index]
        {
            get { return (LimitElement)BaseGet(index); }
            set
            {
                if (BaseGet(index) != null)
                {
                    BaseRemoveAt(index);
                }
                BaseAdd(index, value);
            }
        }
        new public LimitElement this[string employeeID]
        {
            get { return (LimitElement)BaseGet(employeeID); }
        }
        public bool ContainsKey(string key)
        {
            bool result = false;
            object[] keys = BaseGetAllKeys();
            foreach (object obj in keys)
            {
                if ((string)obj == key)
                {
                    result = true;
                    break;
                }
            }
            return result;
        }
    }
    public class LimitElement : ConfigurationElement
    {
        [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
        public string Name
        {
            get { return this["name"] as string; }
            set  {  this["name"] = value;  }
        }

        [ConfigurationProperty("weight", IsRequired = false)]
        public string Weight
        {
            get  {  return this["weight"] as string;  }
            set {  this["weight"] = value; }
        }

        [ConfigurationProperty("length", IsRequired = false)]
        public string Length
        {
            get  {  return this["length"] as string; }
            set  { this["length"] = value;  }
        }
        [ConfigurationProperty("width", IsRequired = false)]
        public string Width
        {
            get  { return this["width"] as string; }
            set  { this["width"] = value;  }
        }
        [ConfigurationProperty("height", IsRequired = false)]
        public string Height
        {
            get  { return this["height"] as string; }
            set { this["height"] = value;  }
        }
        [ConfigurationProperty("square", IsRequired = false)]
        public string Square
        {
            get {  return this["square"] as string;  }
            set  { this["square"] = value; }
        }

        // for total consignment

        [ConfigurationProperty("max-eu", IsRequired = false)]
        public string MaxEU
        {
            get  {  return this["max-eu"] as string;  }
            set  {  this["max-eu"] = value;  }
        }
        [ConfigurationProperty("max-world", IsRequired = false)]
        public string MaxWorld
        {
            get  { return this["max-world"] as string; }
            set  { this["max-world"] = value;  }
        }
    }
}

The c# configuration collection/elements to read the 'service' for each carrier: 用于读取每个运营商的“服务”的c#配置集合/元素:

namespace SmallWFApp
{
    public class ServiceElementCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ServiceElement();
        }
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ServiceElement)element).Name;
        }
        public override ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.BasicMap; }
        }
        protected override string ElementName
        {
            get { return "service"; }
        }
        public ServiceElement this[int index]
        {
            get { return (ServiceElement)BaseGet(index); }
            set
            {
                if (BaseGet(index) != null)
                {
                    BaseRemoveAt(index);
                }
                BaseAdd(index, value);
            }
        }
        new public ServiceElement this[string employeeID]
        {
            get { return (ServiceElement)BaseGet(employeeID); }
        }
        public bool ContainsKey(string key)
        {
            bool result = false;
            object[] keys = BaseGetAllKeys();
            foreach (object obj in keys)
            {
                if ((string)obj == key)
                {
                    result = true;
                    break;
                }
            }
            return result;
        }
    }
    public class ServiceElement : ConfigurationElement
    {
        [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
        public string Name
        {
            get {  return this["name"] as string; }
            set  { this["name"] = value;  }
        }

        [ConfigurationProperty("caption", IsRequired = true)]
        public string Caption
        {
            get  { return this["caption"] as string; }
            set  { this["caption"] = value;  }
        }

        [ConfigurationProperty("code", IsRequired = true)]
        public string Code
        {
            get  { return this["code"] as string;  }
            set { this["code"] = value;  }
        }

        [ConfigurationProperty("live", IsRequired = false)]
        public string Live
        {
            get  {  return this["live"] as string;  }
            set  {  this["live"] = value; }
        }
    }
}

So when you run it, there is no error, but when you examine the variable in the debugger, the collection of carrier property is null: 因此,当您运行它时,没有错误,但是当您在调试器中检查变量时,carrier属性的集合为null:

?config.Carriers
Count = 0
    AddElementName: "add"
    ClearElementName: "clear"
    CollectionType: BasicMap
    Count: 0
    CurrentConfiguration: null
    ElementInformation: {System.Configuration.ElementInformation}
    ElementName: "carrier"
    ElementProperty: {System.Configuration.ConfigurationElementProperty}
    ...
    Properties: {System.Configuration.ConfigurationPropertyCollection}
    ...

If this contains some obvious faux-pas then I'm sorry, but it's driving me to distraction; 如果这包含一些明显的失败,那么我很抱歉,但它让我分心; I need to have released this fix some days ago! 我需要在几天前发布此修复程序!

您必须在Web.config文件中指定您的自定义配置文件parcelcarriers.config

<CarrierSection configSource="parcelcarriers.config"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM