2010年6月10日

電子メール送ろうぜ!※但しJISに限る

電子メール送信をC#で行うと、自動で文字コードを設定してくれます。
これ便利なんですが、どうしても自動であることの欠点で化けたりする可能性もあるってことです。

「在」っていう字が「込」っていう字になって大騒動しました(^^ゞ
エンコード情報見る限りはJIS式になっているんですが、

?iso-2022-jp?Q?
という形式になっておりました。
ISO-2022-JP(つまりJIS)なんですが、Quoted-printableという形式だそうで、
一部の文字が化けてしまうようです(理由は知りません。調べてないので・・・)

化けないようにするためには
?iso-2022-jp?B?
の形式で送ると良いようです。

いつもお世話になっている
http://dobon.net/vb/dotnet/internet/smtpmailquotedprintable.html
の情報を頼りに7bit設定をするもうまくいかなかったので、
エンコードを手動で行うようにロジックを作ってみました。




  1. public static string WordEncode(string エンコードする文字)
  2. {
  3.  Encoding iso2022jp = Encoding.GetEncoding(50220);
  4.  //Base64でエンコードする
  5.  string ret = Convert.ToBase64String(iso2022jp.GetBytes(エンコードする文字));
  6.  //RFC2047形式に手動で設定する
  7.  ret = string.Format("=?{0}?B?{1}?=", iso2022jp.BodyName, ret);
  8.  return ret;
  9. }

まずはこのメソッドを用意し、文字を手動でエンコードするようにします。


そしてメールを送る本体です。
引数とかは必要に応じて追加しましょう。
メール送信の認証系は要注意ですね、

使っているのは、System.Net.Mailの仲間たちです。
まあ、ちょっと型を検索すれば分かるモノたちばかりですからusingの設定は忘れずにヾ(^-^;)

宛先やCCのアドレスは「;」で繋げて複数設定できるようにしています。


  1. public static bool MailSend()
  2. {
  3.  MailMessage m = new MailMessage();
  4.  try
  5.  {
  6.   // 差出人と宛先を設定します
  7.   MailAddress from = new MailAddress(差出人アドレス, WordEncode(差出人の表示名));
  8.   string[] 宛先アドレス配列 = 宛先アドレス.Split(';');
  9.   for (int i = 0; i < 宛先アドレス配列.Length; i++)
  10.   {
  11.    MailAddress to = new MailAddress(宛先アドレス配列[i], WordEncode(宛先の表示名配列[i]));
  12.    m.To.Add(to);
  13.   }
  14.   if (CCのアドレスを使う場合)
  15.   {
  16.    string[] CC用アドレス配列 = CC用アドレス.Split(';');
  17.    for (int i = 0; i < CC用アドレス配列.Length; i++)
  18.    {
  19.     MailAddress cc = new MailAddress(CC用アドレス配列[i], WordEncode(CC用の表示名配列[i]));
  20.     m.CC.Add(cc);
  21.    }
  22.   }
  23.   m.From = from;
  24.   m.Subject = WordEncode(件名);
  25.   byte[] buf = Encoding.GetEncoding(50220).GetBytes(メール本文);
  26.   MemoryStream mem = new MemoryStream(buf);
  27.   AlternateView alt_msg = new AlternateView(mem, new System.Net.Mime.ContentType("text/plain; charset=" +Encoding.GetEncoding(50220).BodyName));
  28.   alt_msg.TransferEncoding = System.Net.Mime.TransferEncoding.SevenBit;
  29.   m.AlternateViews.Add(alt_msg);
  30.   foreach (string 添付ファイル in 添付ファイルパス)
  31.   {
  32.    Attachment attachment;
  33.    //添付ファイルを指定
  34.    attachment = new Attachment(@添付ファイル);
  35.    //Attachmentsに追加する
  36.    m.Attachments.Add(attachment);
  37.   }
  38.   SmtpClient smtpClient = new SmtpClient(送信メールサーバ, 送信メールポート);
  39.   if (SMTP認証の場合)
  40.   {
  41.    smtpClient.Credentials = new NetworkCredential(認証ユーザ, 認証パスワード);
  42.   }
  43.   if (SMTPにSSLを使う場合)
  44.   {
  45.    smtpClient.EnableSsl = true;
  46.   }
  47.   smtpClient.Send(m);
  48.   m.Dispose();
  49.  }
  50.  catch (Exception e)
  51.  {
  52.   //エラー
  53.   m.Dispose();
  54.   return false;
  55.  }
  56.  return true;
  57. }

いや、文字化けってめんどいですね。
囲い文字とか使う人。ホントに勘弁してください・・・(愚痴です)