【问题标题】:.NET Application Configuration to store email contact information.NET 应用程序配置以存储电子邮件联系信息
【发布时间】:2012-12-05 14:31:33
【问题描述】:

我有一个简单的应用程序,可以向我们的一些内部用户发送状态电子邮件。

我使用一个简单的应用程序配置文件 (App.config) 来存储有关目标用户的电子邮件地址和姓名信息。由于 appSettings 部分似乎只支持简单的键/值对,它目前看起来像这样:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="toName" value="Recipient Name" />
    <add key="toAddr" value="some@email.com" />
    <add key="toName2" value="Another Recipient Name" />
    <add key="toAddr2" value="another@email.com" />
    <add key="ccName" value="An Archive"/>
    <add key="ccAddr" value="copies@email.com"/>
    <add key="ccName2" value="Another Archive"/>
    <add key="ccAddr2" value="morecopies@email.com"/>
  </appSettings>
</configuration>

然后我在代码中单独添加每个收件人。

目前,这意味着每次添加或删除收件人时,我还需要重写代码来处理新的收件人并重新构建和重新部署应用程序

我希望能够存储自定义配置条目,例如:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <recipients>
    <recipient recType="to" recAddr="some@email.com" recName="Recipient Name" />
    <recipient recType="to" recAddr="another@email.com" recName="Another Recipient Name" />
    <recipient recType="cc" recAddr="copies@email.com" recName="An Archive"/>
    <recipient recType="cc" recAddr="morecopies@email.com" recName="Another Archive"/>
  </recipients>
</configuration>

所以我可以遍历它们:

MailMessage message = new MailMessage();
foreach(recipient rec in recipients)
{
  MailAddress mailAddress = new MailAddress(recipient["recAddr"],recipient["recName"]);
  if(recipient["recType"] == "cc")
    message.CC.Add(mailAddress);
  else
    message.To.Add(mailAddress);
}

如何做到这一点?

回答: 使用 Regfor 链接中的示例,我能够构建一个自定义配置部分,其中包含一组自定义 ConfigurationElement,如下所示:

public class RecipientElement : ConfigurationElement
{
    [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
    public string Name
    {
        get
        {
            return (string)base["name"];
        }
    }

    [ConfigurationProperty("mailAddr", IsRequired = true)]
    public string Address
    {
        get
        {
            return (string)base["mailAddr"];
        }
    }

    [ConfigurationProperty("isCC")]
    public bool IsCC
    {
        get
        {
            return (bool)base["isCC"];
        }
    }
}

最后的配置部分:

<recipientSection>
  <recipients>
    <recipient name="Primary recipient" mailAddr="usermailbox@email.com" isCC="false" />
    <recipient name="Archive" mailAddr="copies@email.com" isCC="true" />
  </recipients>
</recipientSection>

循环通过 recipients 集合让我可以添加尽可能多的收件人,因为 SmtpClient 可以让我发送到:)

谢谢大家

【问题讨论】:

  • 您可以创建自定义配置部分,如 stackoverflow.com/questions/758986/… 所述
  • @StuartDunkeld 非常好,正是我一直在寻找的东西,尽管对于这个(接缝的)简单问题似乎有点夸张
  • @MathiasR.Jessen 似乎有些夸大其词,因为您将配置文件用于某些并非设计用于执行的操作。您尝试破解配置文件所花费的时间可能会花在创建您自己的简单 xml 文件上,该文件完全按照您想要的方式设计。
  • 如果您从配置值返回新的 MailAddress(string),您可以将名称和地址放在一个值中。

标签: c# .net


【解决方案1】:

虽然我同意自定义配置部分是一种有效的方法,但可以将多个地址(包括显示名称)放在单个 appSetting 中。例如:

<add key="To" 
  value='"Recipient Name" &lt;some@email.com>, "Another Recipient Name" &lt;another@email.com>'/>

...
string to = ConfigurationManager.AppSettings["To"];
MailMessage m = new MailMessage();
m.To.Add(to);

【讨论】:

    【解决方案2】:

    您可以将名称/地址值存储在每个邮件地址的一个部分中。

    <configuration>
      <configSections>
        <section 
          name="MailAddressing" 
          type="System.Configuration.NameValueFileSectionHandler,System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </configSections>
    
      <MailAddressing>
         <add key="To" value="&quot;An Example&quot; <someone@example.com>;&quot;Second Example&quot; <another@example.com>" />
         <add key="CC" value="someone@example.com" />
         <add key="BCC" value="third@example.com" />
         <add key="From" value="sender@example.com" />
      </MailAddressing>
    </configuration>
    

    然后通过

    访问地址
        NameValueCollection section =
            (NameValueCollection)ConfigurationManager.GetSection("MailAddressing");
    

    也许最简单的序列化解决方案是使用 MailAddress 类中的字符串转换器来处理设置的值。

    // Test data
    var addressList = new[]
        {
            new MailAddress("someone@example.com", "An Example"),
            new MailAddress("another@example.com", "Second Example")
        };
    
    // To String for saving in config
    string strValue = addressList.Select(i => i.ToString())
                .Aggregate((i, j) => i + ';' + j);
    
    // From String for reading from config
    MailAddress[] addressList2 = strValue.Split(';').Select(i => 
                new MailAddress(i)).ToArray();
    

    现在您可以为每个收件人/抄送/密送值设置一个配置设置,按邮件地址分组。它适用于单个或多个地址,无论是否显示名称。

    【讨论】:

    • 是的,我尝试像在您的示例中那样摆弄 NameValueCollection 类型,但我仍然面临键/值限制,并且每个条目有多个属性(名称、地址、to/cc)
    • 我想你会喜欢我添加的内容:)
    【解决方案3】:

    您应该为您的收件人编写自定义配置部分,然后包含此部分。使用自定义部分,您还可以将接收者配置存储在主配置文件之外,并使用 configSource 属性包含它。

    首先你可以看这里: http://haacked.com/archive/2007/03/11/custom-configuration-sections-in-3-easy-steps.aspx

    简而言之,您应该:

    1. 通过继承 ConfigurationElement(对于一个元素)和 ConfigurationElementCollection(对于集合,您需要在您的情况下进行集合,每个接收者将成为连接元素)。示例实现在这里回答: how to have custom attribute in ConfigurationElementCollection?

    2. 在主配置中定义配置部分

    3. 添加您的自定义配置,它可以包含在单独的配置文件中

    【讨论】:

    【解决方案4】:

    在 web.config 中创建自定义部分。您可以在http://haacked.com/archive/2007/03/11/custom-configuration-sections-in-3-easy-steps.aspx 找到一些示例,或者您可以谷歌一下。

    然后,您可以将部分中的实体映射到某种类型的 POCO,如果您将创建用于表示电子邮件接收者的 POCO。

    因此,您只需要使用一组电子邮件接收器来简化您的工作。

    别忘了创建一个发送邮件的服务层。

    所以这里是你必须做的步骤:

    1. 创建自定义配置部分。
    2. 创建电子邮件接收者的 Poco 表示
    3. 将自定义配置中的实体映射到 poco 集合
    4. 创建用于发送电子邮件的服务或简单助手

    顺便说一句,将域/应用程序特定的逻辑分离到单独的文件是一个很好的做法,所以请看看这个链接Moving a custom configuration group to a separate file

    祝你好运!

    【讨论】:

    • 不是 ASP,但我想这无关紧要。但是,我查看了 3-easy-steps 解决方案,示例中的自定义配置元素是独一无二的,即。只有 1 个 BlogSettings 元素。我需要存储元素的集合
    【解决方案5】:

    您可以创建自定义配置部分,请看这里:http://msdn.microsoft.com/en-us/library/2tw134k3(v=vs.100).aspx

    适用于 ASP.NET,我认为也适用于 WPF 和 WinForms。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多