.NET TIPS

JISコード(JIS-2022-JP)でメールを送信するには?[2.0のみ、C#、VB]

デジタルアドバンテージ 岸本 真二郎
2008/01/17

 「.NET Framework 2.0で電子メールを送信するには?」で紹介しているように、.NET Framework 2.0以降では、System.Net.Mail名前空間のMailMessageクラスとSmtpClientクラスを使うことで、プログラムから簡単にメールを送信できる。

 以下にその記述例を示す(以降、上:C#、下:VB)。

using System.Text;
using System.Net.Mail;

public void SendMailUtf8()
{
  SmtpClient smtp =new SmtpClient();
  MailMessage msg = new MailMessage();

  //送信元
  msg.From = new MailAddress("shinj-ki@xxx.co.jp", "岸本");
  // 送信先
  msg.To.Add(new MailAddress("shinj-ki@xxx.co.jp", "岸本"));
  // 件名
  msg.Subject = "UTF-8:これは件名";
  // 本文
  msg.Body = "このメールはUTF-8で送信されます。";

  smtp.Host = "mail.xxx.co.jp"; // SMTPサーバを指定
  smtp.Send(msg);  // メッセージを送信
}
Imports System.Text
Imports System.Net.Mail

Public Sub SendMailUtf8()
  Dim smtp As New SmtpClient()
  Dim msg As New MailMessage()

  ' 送信元
  msg.From = New MailAddress("shinj-ki@xxx.co.jp", "岸本")
  ' 送信先
  msg.To.Add(New MailAddress("shinj-ki@xxx.co.jp", "岸本"))
  ' 件名
  msg.Subject = "UTF-8:これは件名"
  ' 本文
  msg.Body = "このメールはUTF-8で送信されます。"

  smtp.Host = "mail.xxx.co.jp" ' SMTPサーバを指定
  smtp.Send(msg) ' メッセージを送信
End Sub
リスト1 MailMessageクラスとSmtpClientクラスを利用したメールの送信
エンコーディングを指定しない場合は、UTF-8でエンコードされてメールが送信される。

 この場合、送信元、送信先、件名、本文の各文字列はすべて「UTF-8」でエンコードされて送信される。

 最近のメール・クライアントであればUTF-8でエンコードされたメールも問題なく処理できるが、UTF-8をサポートしないメール・クライアントも多く存在する。このため、日本語のメール送信はUTF-8ではなく「JISコード(JIS-2022-JP)」で行うのが一般的だ。

 そこで本稿では、JISコード(JIS-2022-JP)でメールを送信する方法を紹介する。

不適切なJIS-2022-JPによるメール送信

 MailMessageクラスでは、SubjectEncodingプロパティとBodyEncodingプロパティにより、件名と本文のエンコードの指定が可能だ。また送信元、送信先については、アドレス情報であるMailAddressクラス(System.Net.Mail名前空間)を使ってエンコーディングを指定できる。

 そのため、単純にJIS-2022-JPでメールを送ろうとするなら、次のようなコードになる。

using System.Text;
using System.Net.Mail;

// JIS-2022-JPを指定
public void Send_JIS_Mail1()
{
  SmtpClient smtp = new SmtpClient();
  MailMessage msg = new MailMessage();

  Encoding myEnc = Encoding.GetEncoding("iso-2022-jp");

  msg.SubjectEncoding = myEnc; // 件名のエンコーディングを指定
  msg.BodyEncoding = myEnc; // 本文のエンコーディングを指定

  // エンコーディングを指定して、メールアドレス情報を作成
  msg.From = new MailAddress("shinj-ki@xxx.co.jp", "岸本", myEnc);
  msg.To.Add(new MailAddress("shinj-ki@xxx.co.jp", "岸本", myEnc));

  msg.Subject = "JIS-EX1:文字化け注意";
  msg.Body = "Send_JIS_Mail1()  ライブラリのエンコーディングを指定。";

  smtp.Host = "mail.xxx.co.jp";
  smtp.Send(msg);
}
Imports System.Text
Imports System.Net.Mail

' JIS-2022-JPを指定
Public Sub Send_JIS_Mail1()

  Dim smtp As New SmtpClient()
  Dim msg As New MailMessage()

  Dim myEnc As Encoding = Encoding.GetEncoding("iso-2022-jp")

  msg.SubjectEncoding = myEnc ' 件名のエンコーディングを指定
  msg.BodyEncoding = myEnc ' 本文のエンコーディングを指定

  ' エンコーディングを指定して、メールアドレス情報を作成
  msg.From = New MailAddress("shinj-ki@xxx.co.jp", "岸本", myEnc)
  msg.[To].Add(New MailAddress("shinj-ki@xxx.co.jp", "岸本", myEnc))

  msg.Subject = "JIS-EX1:文字化け注意"
  msg.Body = "Send_JIS_Mail1()  ライブラリのエンコーディングを指定。"

  smtp.Host = "mail.xxx.co.jp"
  smtp.Send(msg)
End Sub
リスト2 JIS-2022-JPを指定してメールを送る

 ところが、このような指定を行ってメールを送信すると、メール・クライアントによっては正しく日本語が表示されない場合がある。詳細は省略するが、メール・ヘッダに含まれる文字列のMIMEエンコード処理がJISコードにふさわしくない方法で行われているためである。

メール・ヘッダのエンコード

 メール・ヘッダにおけるMIMEエンコーディングを正しく行うには、自前でエンコード処理を用意すればよい。といってもそれほど大変なことではなく、文字列をBase64でエンコードするメソッドを用意するだけだ。

 文字列のBase64エンコーディングにはConvertクラス(System名前空間)のToBase64Stringメソッドが利用できる。次のリスト3にその記述例を示す。

private string myEncode(string str, System.Text.Encoding enc)
{
  string base64str = Convert.ToBase64String(enc.GetBytes(str));
  return string.Format("=?{0}?B?{1}?=", enc.BodyName, base64str);
}
Private Function myEncode(ByVal str As String, ByVal enc As System.Text.Encoding) As String
  Dim base64str As String = _
      Convert.ToBase64String(enc.GetBytes(str))
  Return String.Format("=?{0}?B?{1}?=", enc.BodyName, base64str)
End Function
 リスト3 文字列をBase64に変換するメソッド

 リスト3のmyEncodeメソッドは、変換したい文字列とエンコーディングを引数に取る。メソッド内では、文字列をエンコーディングに従ったバイト列に変換してから、Base64に変換する。そして変換された文字列をRFC2047の形式に整形している。

 このメソッドを使って、メールの送信先、送信元、件名を標準的なMIMEエンコーディングに設定できるようになる。例えば上記のメールアドレスの「岸本」の部分をこのメソッドによりエンコードすると、次のような文字列になる。

=?iso-2022-jp?B?GyRCNF9LXBsoQg==?=

 この場合には、自前でエンコーディングを行うので、MailMessageクラスでのエンコーディングの指定は不要だ。

本文のエンコード

 残るは本文のエンコードだが、これにはAlternateViewクラス(System.Net.Mail名前空間)が使用できる。このクラスは、メールにプレーン・テキストとHTML形式のテキストの両方を含めて送信する場合などに利用するものだが、これを使うことでメール本文をより一般的な形式にできる。

 AlternateViewクラスを使う場合のポイントは、メディア・タイプとして「System.Net.MimeMediaTypeNames.Text.Plain*1」(=プレーン・テキスト)を指定することと、TransferEncodingプロパティに「System.Net.Mime.TransferEncoding.SevenBit*2」を指定することである。もちろんエンコーディングはJIS-2022-JPを指定する。

*1 System.Net名前空間のMimeMediaTypeNames.TextクラスのPlainフィールド。
*2 System.Net.Mime名前空間のTransferEncoding列挙体の値「SevenBit」。

 以下に、AlternateViewクラスの利用例を示す。

// 変数sBody:メール本文
// 変数myEnc:エンコーディング(ここではJIS-2022-JP)
AlternateView altView =
  AlternateView.CreateAlternateViewFromString(
    sBody, myEnc, System.Net.Mime.MediaTypeNames.Text.Plain);

// Content-Transfer-Encoding: 7bit
altView.TransferEncoding =
  System.Net.Mime.TransferEncoding.SevenBit;
msg.AlternateViews.Add(altView); // altViewをメッセージに追加
' 変数sBody:メール本文
' 変数myEnc:エンコーディング(ここではJIS-2022-JP)
Dim altView As AlternateView = _
  AlternateView.CreateAlternateViewFromString( _
    sBody, myEnc, System.Net.Mime.MediaTypeNames.Text.Plain)

' Content-Transfer-Encoding: 7bit
altView.TransferEncoding = System.Net.Mime.TransferEncoding.SevenBit
msg.AlternateViews.Add(altView) // altViewをメッセージに追加
リスト4 AlternateViewクラスを使って本文をセットする

 本文としてAlternateViewオブジェクトを指定したので、メール本文(MailMessage.Body)には何もセットしない。AlternateViewオブジェクトに上記のエンコーディング情報を指定することで、メール・ヘッダには、以下の2つの行が記述されるようになる。

Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

 なお、サービスパックがインストールされていない.NET Framework 2.0では、「Content-Transfer-Encoding: sevenbit」と誤った記述になる場合があるので、最新のサービスパックをインストールしておく必要がある。

JIS-2022-JPでメールを送信する処理

 以上をまとめると、JIS-2022-JPでメールを送信する処理は次のようになる。

using System.Text;
using System.Net.Mail;

private string myEncode(string str, System.Text.Encoding enc)
{
  string base64str = Convert.ToBase64String(enc.GetBytes(str));
  return string.Format("=?{0}?B?{1}?=", enc.BodyName, base64str);
}

private void Send_JIS_Mail()
{
  SmtpClient smtp = new SmtpClient();
  MailMessage msg = new MailMessage();
  Encoding myEnc = Encoding.GetEncoding("iso-2022-jp");

  // 送信元
  msg.From = new MailAddress(
                "shinj-ki@xxx.co.jp", myEncode("岸本", myEnc));
  // 送信先
  msg.To.Add(new MailAddress(
                "shinj-ki@xxx.co.jp", myEncode("岸本", myEnc)));
  // 件名
  msg.Subject = myEncode("EX-4:件名はabcです", myEnc);

  // 本文
  string sBody =
    "Send_JIS_Mail()\r\n"
    + " AlternateViewによる本文の指定を行いました。";
  AlternateView altView =
    AlternateView.CreateAlternateViewFromString(
        sBody, myEnc, System.Net.Mime.MediaTypeNames.Text.Plain);
  altView.TransferEncoding =
    System.Net.Mime.TransferEncoding.SevenBit;
  msg.AlternateViews.Add(altView);

  smtp.Host = "mail.xxx.co.jp"; // SMTPサーバ
  smtp.Send(msg); // メッセージを送信
}
Imports System.Text
Imports System.Net.Mail

Private Function myEncode(ByVal str As String, ByVal enc As System.Text.Encoding) As String
  Dim base64str As String = Convert.ToBase64String(enc.GetBytes(str))
  Return String.Format("=?{0}?B?{1}?=", enc.BodyName, base64str)
End Function

Private Sub Send_JIS_Mail()
  Dim smtp As New SmtpClient()
  Dim msg As New MailMessage()
  Dim myEnc As Encoding = Encoding.GetEncoding("iso-2022-jp")

  ' 送信元
  msg.From = New System.Net.Mail.MailAddress( _
                  "shinj-ki@xxx.co.jp", myEncode("岸本", myEnc))
  ' 送信先
  msg.[To].Add(New System.Net.Mail.MailAddress( _
                  "shinj-ki@xxx.co.jp", myEncode("岸本", myEnc)))
  ' 件名
  msg.Subject = myEncode("EX-4:件名はabcです", myEnc)

  ' 本文
  Dim sBody As String = _
    "Send_JIS_Mail()" & Chr(13) & "" & Chr(10) & _
      " AlternateViewによる本文の指定を行いました。"
  Dim altView As AlternateView = _
    AlternateView.CreateAlternateViewFromString( _
      sBody, myEnc, System.Net.Mime.MediaTypeNames.Text.Plain)
  altView.TransferEncoding = _
    System.Net.Mime.TransferEncoding.SevenBit
  msg.AlternateViews.Add(altView)

  smtp.Host = "mail.xxx.co.jp" ' SMTPサーバ
  smtp.Send(msg) ' メッセージを送信
End Sub
リスト5 JIS-2022-JPでメールを送信する処理
このコードにより、通常のメール・クライアントに近いエンコード処理でメールを送ることができる。

 このリスト5により最終的に送信されるメールは次のような内容となる(一部を抜粋)。

MIME-Version: 1.0
From: =?iso-2022-jp?B?GyRCNF9LXBsoQg==?= <shinj-ki@xxx.co.jp>
To: =?iso-2022-jp?B?GyRCNF9LXBsoQg==?= <shinj-ki@xxx.co.jp>
Date: 12 Jan 2008 01:44:45 +0900
Subject: =?iso-2022-jp?B?RVgtNDobJEI3b0w+JE8bKEJhYmMbJEIkRyQ5GyhC?=
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

Send_JIS_Mail()
 AlternateViewによる本文の指定を行いました。

リスト6 リスト5のメソッドを利用して送信されたメールの内容例(一部を抜粋)

 ヘッダ部分を見ると、送信元、送信先、件名がJIS-2022-JPでエンコードされ、2つのContent-XXXが追加されているのが確認できる。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:電子メール
使用ライブラリ:MailMessageクラス(System.Net.Mail名前空間)
使用ライブラリ:SmtpClientクラス(System.Net.Mail名前空間)
使用ライブラリ:MailAddressクラス(System.Net.Mail名前空間)
使用ライブラリ:Convertクラス(System名前空間)
使用ライブラリ:AlternateViewクラス(System.Net.Mail名前空間)
使用ライブラリ:MimeMediaTypeNames.Textクラス(System.Net名前空間)
使用ライブラリ:TransferEncoding列挙体(System.Net.Mime名前空間)
関連TIPS:.NET Framework 2.0で電子メールを送信するには?

この記事と関連性の高い別の.NET TIPS
電子メールを送信するには?
.NET Framework 2.0で電子メールを送信するには?
文字列をBase64でエンコード/デコードするには?
プログラムからブラウザやメーラを起動するには?
[ASP.NET]PasswordRecoveryコントロールのパスワード通知メールをカスタマイズするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間