2014/10/12

【C#】テンプレートメッセージを使ってメールを送信する

メールを送る処理は、C#でコンソールアプリケーションを作っているとよくある。
ただ、コード内にメール内容を書いてしまうと、修正が困難になる。

そこでメールのテンプレートをテキスト形式で外出しにし、C# で読み込み編集してメールを送る処理をつくってみた。

以降、私が実際に作成した「処理の完了を通知するアプリ」を例にとって説明していく。


テンプレートを使ってメールを送信する



まずはテンプレートを、以下のような形式で「MailTemplate.txt」というファイル名で作成する。
%~% の部分はパラメータとし、処理内で書き換える。
メンバー各位

処理日:%DATE%

処理が完了しました。
結果の確認、よろしくお願いいたします。

----以下、処理結果--------------------------------------------
%MESSAGE%
----------------------------------------------------------------

以上

次に必要なのは、メールの送信用の設定ファイル。
これはConfigファイルとして作成する。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="from" value="b.c.rikko@blackeveryday.co.jp"/>
    <add key="to" value="member1@blackeveryday.co.jp;member2@blackeveryday.co.jp"/>
    <add key="smtp" value="smtp.blackeveryday.co.jp"/>
    <add key="port" value="25"/>
    <add key="user" value="bc_rikko"/>
    <add key="pass" value="password"/>
    <add key="subject" value="【通知】処理完了報告 "/>
    <add key="body" value="./MailTemplate.txt"/>
  </appSettings>
</configuration>


最後にC# の処理を作成する。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;
// ↑ 必要に応じて追加してください(もしかしたら足りないかも)

// メール送信
public void SendMail(string message)
{
    // Configファイルの読み込み
    var conf = ReadConfig();
    var enc = Encoding.GetEncoding("shift_jis");

    using (var smtp = new SmtpClient())
    using (var msg = new MailMessage())
    {
        msg.SubjectEncoding = enc;
        msg.BodyEncoding = enc;
        
        // 件名
        msg.Subject = conf["subject"] 
                              + DateTime.Now.ToString("yyyyMMdd");

        // 本文
        using (var sr = new StreamReader(conf["body"], enc))
        {
            // パラメータ(%~%)の置換
            msg.Body = sr.ReadToEnd()
                   .Replace("%DATE%", DateTime.Now.ToString("yyyy/MM/dd"))
                   .Replace("%MESSAGET%", message);
        }

        // 差出人(From)
        msg.From = new MailAddress(conf["from"]);

        // 宛先(To)を複数登録する
        foreach (var to in conf["to"].Split(';'))
        {
            msg.To.Add(new MailAddress(to));
        }

        // SMTPサーバの設定
        smtp.Host = conf["smtp"];
        smtp.Port = Convert.ToInt32(conf["port"]);
        
        // SMTP認証
        if (!String.IsNullOrEmpty(conf["user"]) 
            && !String.IsNullOrEmpty(conf["pass"]))
        {
            smtp.Credentials = new NetworkCredential(conf["user"]
                                                   , conf["pass"]);
        }
        // メール送信
        smtp.Send(msg);
    }
}


// Configファイルの読み込み
private Dictionary<string, string> ReadConfig()
{
    var configs = new Dictionary<string, string>();

    ConfigurationManager.OpenExeConfiguration(@Process.GetCurrentProcess().MainModule.FileName);
    
    foreach (var key in ConfigurationManager.AppSettings.AllKeys)
    {
        configs[key] = ConfigurationManager.AppSettings[key];
    }

    return configs;
}


MailMessageクラスとSmtpClientクラスを使っている。
MailMessgeクラスでは、送信するメッセージの組み立て。
SmptClientクラスでは、SMTPを利用したメールの送信を行う。



ポイントは、msg.Body = sr.ReadToEnd().Replace.Replaceのところ。
ここでパラメータとして設定した「%DATE%」と「%MESSAGE%」を置換している。
Configファイルをうまく使えば、パラメータとそこに設定する値も外出しで管理できる気がする。


宛先(To)に複数設定する方法は、単純にConfigファイルの「key="to"」にセミコロン区切りで複数のメールアドレスを設定し、内部でセミコロンで切り分けmsg.Toに追加していく。
To.Add()はコレクション型の引数をとるので、Listとかと同じ感覚で設定していけば問題ない


smtp.Credentialsは、Configに設定されているユーザとパスワードを使ってSMTP認証を行っている。



Configファイルの読み込みについては、Visual StudioなどのIDEを使っていれば「ConfigurationManager.OpenExeConfiguration」が不要。
プロジェクトファイルを作れないようなテキストエディタでの開発のときのみ必要になる。

詳しくは、「【C#】csc.exeでコンパイルするときにConfigファイルを読み込む」を参照。


Tips的要素としては、IDisposableを継承しているクラスはusingでくくると、ブロックを抜けたときに勝手にDisposeしてくれるので、try - finallyで書く必要はない。

また、usingを2重で書く場合は、ソースコードのように単純に2行連続して書き、その後ブロックを作れば良い。



参考



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿