SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

現役エンジニア直伝! 「現場」で使えるコンポーネント活用術(Secure Mail)

日本語メールの送信で起こりうる予期せぬクレーム~.NET Framework標準機能と市販コンポーネント「Secure Mail」を徹底比較~

Secure Mailを使ったメール送信システム構築

  • X ポスト
  • このエントリーをはてなブックマークに追加

エンコードを指定してメールを送信する

 Sendメソッドでシンプルにメール送信した場合、どちらを使っても日本語の扱いが心許なかったと思います。そこで次に、エンコードを指定するコードを追加した場合の送信メールについて確認してみましょう(サンプル「CZ1003Message」)。

図5 Charsetでエンコード指定
図5 Charsetでエンコード指定

System.Net.Mailの使用方法

リスト8 System.Net.Mailでのエンコード指定コード
Using msg As New System.Net.Mail.MailMessage
    msg.To.Add(New System.Net.Mail.MailAddress(Me.To_TextBox.Text.Trim))
    msg.From = New System.Net.Mail.MailAddress(Me.From_TextBox.Text.Trim)
    msg.Subject = "[SNM]" & Me.Subject_TextBox.Text.Trim
    msg.Body = Me.MailText_TextBox.Text
    msg.SubjectEncoding = System.Text.Encoding.GetEncoding("iso-2022-jp")
    msg.BodyEncoding = msg.SubjectEncoding
    msg.Headers.Add("Content-Transfer-Encoding", "7bit")
    Try
        Dim smtp As New System.Net.Mail.SmtpClient 'IDisposeを実装してない
        smtp.Host = Me.Server_TextBox.Text.Trim
        smtp.Port = Me.Port_TextBox.Text.Trim
        smtp.Credentials = New NetworkCredential(Me.UserId_TextBox.Text.Trim, _
                                                 Me.Password_TextBox.Text.Trim)
        smtp.Timeout = 100000
        smtp.Send(msg)
         isOK = True
        MessageBox.Show("Sytem.Net.Mail送信終了")
    Catch ex As Exception
        MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    Finally
    End Try
End Using

 System.Net.Mailでエンコードを指定するときには、System.Net.Mail.MailMessageを使ってSubjectEncodingとBodyEncodingにSystem.Text.Encoding.GetEncoding("iso-2022-jp")を指定します。Content-Transfer-Encodingヘッダについては、Headers.Addメソッドによって明示的に指定します。

 まず注目してほしいのは、SubjectとBodyにはEncoding指定があるのに、ToやFromには存在しない点です。ToやFromにエンコードを施すには、System.Net.Mail.MailAddressの指定を次のようにしなければなりません。

msg.To.Add(New MailAddress(Me.To_TextBox.Text.Trim),"表示名",GetEncoding("iso-2022-jp"))

 よって、図5のように表示名も同時に指定できるような場合は、メールアドレスと表示名に切り分ける必要があります。

 このコードを使って送信したメールをBecky!で受信すると、ToやFromの表示名、Subjectの日本語が文字化けしてしまいます。Becky!の[表示]-[ソースの表示]で確認してみます。

リスト9 System.Net.Mail.SmtpClientからのメール
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
From: =?utf-8?Q?=E5=88=9D=E9=9F=B3=E7=8E=B2?= <hatsune@wankuma.com>
To: =?utf-8?Q?=E5=88=9D=E9=9F=B3=E7=8E=B2?= <hatsune@wankuma.com>
Date: 15 Mar 2010 23:26:24 +0900
Subject: =?iso-2022-jp?Q?[SNM]Charset=1B$B@_DjF|K\8l$N7oL>$,$I$&=3DhM}$5$l$k$+$N=1B(Btest=1B$BMQ7oL>=1B(B?=
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: quoted-printable

=1B$BF|K\8lK\J8=1B(B

 Content-Transfer-Encodingヘッダが2種類あったり、Content-TypeヘッダでISO-2022-JPを指定しているのにToとFromの表示名はUTF-8で扱われていたりと、不思議な内容になっています。

 また、Subjectや本文は確かにISO-2022-JPのコード系のようですが、7bitの指定は無視され、Qエンコードされてquoted-printableになっているなど、やはり日本でのデファクトスタンダードに合った形式では遅れませんでした。Becky!は比較的文字化けが起こらないメールクライアントソフトですが、そのメールクライアントソフトですらお手上げのようです。

Dart.PowerTCP.SecureMailの使用方法

リスト10 SecureMailでのエンコード指定コード
Using msg As New Dart.PowerTCP.SecureMail.MessageStream
    msg.To.Add(New Dart.PowerTCP.SecureMail.MailAddress(Me.To_TextBox.Text.Trim))
    msg.From = New Dart.PowerTCP.SecureMail.MailAddress(Me.From_TextBox.Text.Trim)
    msg.Subject = "[GSM]" & Me.Subject_TextBox.Text.Trim
    msg.Text = Me.MailText_TextBox.Text
    msg.Charset = "ISO-2022-JP"
    msg.ContentType = "text/plain"
    msg.Header.Add(Dart.PowerTCP.SecureMail.HeaderLabelType.ContentTransferEncoding, "7bit")
    Try
        Using smtp As New Dart.PowerTCP.SecureMail.Smtp
            smtp.Server = Me.Server_TextBox.Text.Trim
            smtp.ServerPort = Me.Port_TextBox.Text.Trim
            Select Case True
                Case Me.AuthLogin_RadioButton.Checked
                    smtp.LoginMethod = Dart.PowerTCP.SecureMail.SmtpLoginMethod.AuthLogin
                Case Me.AuthPlain_RadioButton.Checked
                    smtp.LoginMethod = Dart.PowerTCP.SecureMail.SmtpLoginMethod.AuthPlain
                Case Me.AuthMd5_RadioButton.Checked
                    smtp.LoginMethod = Dart.PowerTCP.SecureMail.SmtpLoginMethod.AuthCramMd5
            End Select
            smtp.Username = Me.UserId_TextBox.Text.Trim
            smtp.Password = Me.Password_TextBox.Text.Trim
            smtp.Send(msg)
            smtp.Close()
        End Using
        isOK = True
        MessageBox.Show("SecureMail送信終了")
    Catch ex As Exception
        MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Try
End Using

 System.Net.Mail.SmtpClientと異なり、SecureMailでは個別にエンコードを指定するのではなくDart.PowerTCP.SecureMail.MessageStream全体に対して指定を行います。

msg.Charset = "ISO-2022-JP"
msg.ContentType = "text/plain"

 そのため、リストにあるように表示名も含んだ形で処理しても、指定されたエンコードの対象になります。なお、Content-Transfer-Encodingヘッダの省略値は7bitなので、Header.Addメソッドによって明示的に追加を行わなくても問題ありません。

 このコードを使って送信したメールをBecky!の[表示]-[ソースの表示]で確認すると、次のようにMIME形式でISO-2022-JPで7bitエンコードされたメールになります。これがデファクトスタンダードの日本語メールです。

リスト11 SecureMailからのメール
From: "=?iso-2022-jp?B?GyRCPWkyO05oGyhC?=" <hatsune@wankuma.com>
To: "=?iso-2022-jp?B?GyRCPWkyO05oGyhC?=" <hatsune@wankuma.com>
Subject: [GSM]Charset=?iso-2022-jp?B?GyRCQF9EakZ8S1w4bCRON29MPiQsJEkkJj1oTX0kNSRsJGskKyROGyhCdGVzdBskQk1RN29MPhsoQg==?=
Content-Type: text/plain; charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
Date: Mon, 15 Mar 2010 23:26:29 +0900
MIME-Version: 1.0

$BF|K\8lK\J8(B

 惜しむらくは、若干ではありますが、Subjectなどが72バイトよりも長くなった時の折り返しの関係で文字化けする可能性があることです。

次のページ
RFC違反のメールアドレス宛に送信する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
現役エンジニア直伝! 「現場」で使えるコンポーネント活用術(Secure Mail)連載記事一覧
この記事の著者

初音玲(ハツネアキラ)

 国内SIerのSEでパッケージ製品開発を主に行っており、最近は、空間認識や音声認識などを応用した製品を手掛けています。 個人的には、仕事の内容をさらに拡張したHoloLensなどのMRを中心に活動しています。 Microsoft MVP for Windows Development ブログ:http://hatsune.hatenablog.jp/

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5042 2010/03/30 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング