Есть ли способ использовать словарную коллекцию в качестве объекта настроек приложения? - PullRequest
2 голосов
/ 08 июня 2009

Я хотел бы сохранить набор пар ключ / значение в настройках приложения моего веб-приложения ASP.NET, но я не нахожу простой способ сделать это. Например, эти два вопроса говорят мне, что StringDictionary и т. Д. Не будут сериализоваться в XML, и предлагают мне свернуть мою собственную реализацию. Но кажется, что это должно быть легче сделать; в конце концов, web.config - это XML, а - это, по сути, коллекция пар ключ / значение, поэтому мне кажется, что я упускаю что-то очевидное. Учитывая мой конкретный случай ниже, действительно ли мне нужно свернуть мою собственную сериализацию, или есть более простой обходной путь?

Рассматриваемое веб-приложение представляет собой базовую контактную форму, которая отправляет электронную почту различным получателям в зависимости от значения параметра; например http://www.examplesite.com/Contact.aspx?recipient=support отправит письмо на SupportGroup@exampledomain.com.

Цель состоит в том, чтобы иметь возможность добавлять или удалять получателей (или изменять их адреса) путем редактирования файла web.config, чтобы мне не приходилось перекомпилировать и легко поддерживать различные конфигурации в тестовой и производственной средах. Например:

// I can use something like this for the sender address
SmtpMsg.From = New MailAddress(My.Settings.EmailSender)

// And then just edit this part of web.config to use 
// different addresses in different environments.
<setting name="EmailSender" serializeAs="String">
 <value>webcontact@exampledomain.com</value>
</setting>

// I want something like this for the recipients
SmtpMsg.To.Add(My.Settings.Recipients("support"))

// and presumably some sort of equivalent xml in web.config
// maybe something like this???
<recipients>
  <item name="support" serializeAs="String">
   <value>SupportGroup@exampledomain.com</value>
  </item>
  <!-- add or remove item elements here -->
</recipients>

edit: заменены комментарии VB с комментариями C # из-за раскраски кода

Ответы [ 2 ]

5 голосов
/ 09 июня 2009

Самым простым способом, очевидно, было бы просто сбросить их в настройках приложения, но это было бы не очень аккуратно:

<appSettings>
  <add key="EmailSupport" value="support@somedomain.com" />
  <add key="EmailSales" value="sales@somedomain.com" />
</appSettings>

Тогда в вашем коде вы просто делаете что-то вроде:

if (!string.IsNullOrEmpty(Request["recipient"])) {
  string recipientEmail = 
         WebConfigurationManager.AppSettings["Email" + Request["recipient"]];
  // Send your email to recipientEmail
}

Если вы хотите быть немного аккуратнее, вы можете создать пользовательский раздел конфигурации следующим образом (я боюсь, C #, но в документах есть VB ): 1011 *

namespace EmailSystem {
  public class EmailRecipientsSection : ConfigurationSection {
    [ConfigurationProperty("emailSender", IsRequired = true, IsKey = false)]
    public string EmailSender {
        get { return (string)this["name"]; }
        set { this["name"] = value; }
    }

    [ConfigurationProperty("emailRecipients", IsDefaultCollection = true)]
    public EmailRecipientCollection EmailRecipients {
      get {
        var emailRecipientCollection = 
              (EmailRecipientCollection) base["emailRecipients"];
        return emailRecipientCollection;
      }
    }
  }

  public class EmailRecipientCollection : ConfigurationElementCollection {
    public EmailRecipientElement this[int index] {
      get { return (EmailRecipientElement) BaseGet(index); }
      set {
        if (BaseGet(index) != null) {
          BaseRemoveAt(index);
        }
        BaseAdd(index, value);
      }
    }

    public new EmailRecipientElement this[string name] {
      get { return (EmailRecipientElement) BaseGet(name); }
    }

    protected override ConfigurationElement CreateNewElement() {
      return new EmailRecipientElement();
    }

    protected override object GetElementKey(ConfigurationElement element) {
      return ((EmailRecipientElement) element).Name;
    }
  }

  public class EmailRecipientElement : ConfigurationElement {
    [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
    public string Name {
      get { return (string) this["name"]; }
      set { this["name"] = value; }
    }

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

Тогда в вашем web.config есть что-то вроде этого:

<configSections>
  [...]
  <section name="EmailSystem" type="EmailSystem, AssmeblyName" />
</configSections>

<EmailSystem emailSender="fromAddress@somedomain.com">
  <emailRecipients>
    <clear />
    <add name="Support" emailAddress="support@somedomain.com" />
    <add name="Sales" emailAddress="sales@somedomain.com" />
  </emailRecipients>
</EmailSystem>

Тогда вы можете позвонить в это:

emailRecipient = Request["recipient"];

var emailSystem = ConfigurationManager.GetSection("EmailSystem")
                    as EmailRecipientsSection;

string recipientEmail = emailSystem.EmailRecipients[emailRecipient].emailAddress;

// send email to recipientEmail.
3 голосов
/ 09 июня 2009

Вы можете сделать пару вещей, хотя, честно говоря, я думаю, что это проще всего:

<appSettings>
    <add key="testValues" value="someone@abc.com, someoneElse@abc.com, yetAnotherSomeone@abc.com" />
</appSettings>

Тогда вы можете получить свой объект через:

String[] temp =
ConfigurationManager.AppSettings.GetValues("testValues").ToString().Split(',');

, а затем выполните простое утверждение foreach для извлечения. Вы можете даже установить это как статический объект для кэширования, чтобы его можно было быстрее восстановить. :)

Надеюсь, это поможет,

JP

РЕДАКТИРОВАТЬ: альтернативный сценарий включает в себя:

<appSettings file="test.config">
<!-- other settings to default to if test.config doesn't exist -->
</appSettings>

В этом случае, если в вашей тестовой среде существует файл test.config, для этого файла будет выполнен вызов AppSettings.GetValues ​​(). Если файл test.config не существует, класс ConfigurationManager будет использовать значения в узле appSettings в файле web.config.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...