System.Net.Mail.SmtpClientクラス、System.Net.Mail.MailMessageクラスを使ったメールの送信方法、メール作成時の注意点など。
以下の内容は主に.NET Framework 4以降を対象としている。 サンプルコードは.NET Framework 4.5およびMono 3.8で動作検証済み。
メールの送信
SMTPサーバーのホスト名とポート番号を指定してSmtpClientのインスタンスを作成し、Sendメソッドを呼び出すことで指定した宛先にメールを送ることができる。
SmtpClient(System.Net.Mail名前空間)はSystem.dllに含まれているため、ほとんどの場合は参照の追加を行う必要なく使用することができる。
SMTPサーバーの接続時に認証が必要になる場合はCredentialsプロパティ、SSLでの接続(あるいはSTARTTLS)が必要になる場合はEnableSslプロパティを設定する。 以下はGMail SMTPサーバーを使ってGMailアカウントからメールを送信する例。
MailMessageクラスを使うと、送信するメールの内容を細かく指定することができる。 例えば送信先に複数のメールアドレスを指定したり、ヘッダを設定したりすることができる。
本文や件名に日本語などを使用する方法、文字コードに関する注意点などは後述する。
MailMessageクラス
MailMessageクラスは送信するメールを組み立てるためのクラス。 メールヘッダ・文字コードなどに関する設定や、ファイルの添付を行いたい場合はこのクラスを使ってメールを作成する。
本文の文字コード
本文の文字コードを指定する場合は、BodyEncodingプロパティにEncodingクラスを指定する。 SmtpClientは指定された文字コードを使用して本文をエンコードし、送信する。 この際、UTF-8, UTF-16, UTF-32の場合にはContent-Transfer-Encoding
にBASE64が使用され、それ以外の場合にはquoted-printableが使用される。
件名(Subject)の文字コード
件名(Subject)の文字コードを指定する場合は、本文の場合と同様SubjectEncodingプロパティにEncodingクラスを指定する。 SmtpClientは指定された文字コードを使用して件名をエンコードし、送信する。
.NET Frameworkでは、本文と同様UTF-8, UTF-16, UTF-32の場合にはBASE64(Bエンコード)、それ以外の場合にはquoted-printable(Qエンコード)が使用される。 Mono 3.8時点では、文字コードに関わらず常にquoted-printable(Qエンコード)が使用される模様。
件名にBエンコードを使用したい場合
件名にBエンコード(BASE64)を使用した文字列を指定したい場合は、次のようにする。
- .NET Framework 4.5以降の場合
- SubjectEncodingプロパティを設定せず、Bエンコードを二回施した文字列をSubjectプロパティに設定する
- .NET Framework 4.0以前の場合
- SubjectEncodingプロパティを設定せず、Bエンコードを施した文字列をSubjectプロパティに設定する
なお、version 3.8時点のMonoでも、.NET Framework 4.0以前と同じくBエンコードを1度だけ施した文字列を設定することにより件名にBエンコードを使用することができる。
差出人(From)・宛先(To)・CCなどメールアドレスの表示名と文字コード
メールアドレスを文字列ではなくMailAddressクラスで渡すと、アドレスの表示名(DisplayName)を指定することができる。 表示名の文字コードにはUTF-8が用いられ、Qエンコードされる。
他の文字コードを指定したり、Bエンコードを使用したい場合は、エンコード済みの文字列をDisplayNameに指定すれば、そのまま送信される。
HTMLメールの送信
IsBodyHtmlプロパティをtrue
にすると、Bodyプロパティに設定した内容をHTML(text/html)として送信することができる。
ファイルの添付
送信するメールにファイルを添付したい場合はAttachmentクラスを使用する。 添付したいファイルごとにAttachmentを作成し、Attachmentsプロパティに追加する。
Mono 3.8の時点では、Attachment.ContentDispositionのFileNameプロパティを設定していなくてもContent-Disposition
ヘッダにfilename
パラメータが設定されるが、その内容が正しくエンコードされないため注意が必要。
関連: MIMEタイプの取得・判定
ヘッダの長さと折り返し
SubjectプロパティやHeadersプロパティでヘッダの内容を指定する場合、長さは特に制限されない上、ヘッダの折り返しもされない模様。
.NET Frameworkでは半角空白が含まれている個所で自動的に折り返しが行われる。 一方Monoではこの場合も折り返されずにそのまま送信される。
また、Subjectプロパティに設定する文字列に改行とタブを含めることによって強制的にヘッダの折り返しを行わせる方法については、.NET FrameworkではArgumentExceptionとなるため使用できない。 一方Monoではこの方法によってヘッダの折り返しを行うことができる。
SubjectプロパティではなくHeadersプロパティを使ってヘッダに直接値を設定することもできるが、この方法はMonoのみで使用できる。 .NET Frameworkの場合、Headersプロパティを使って値を設定してもSubjectヘッダには反映されない(Subjectヘッダが設定されず、件名が空になる)。
ヘッダの折り返しではなく改行文字そのものを件名に含めたい場合などは、Bエンコード(あるいはQエンコード)した文字列を設定する必要がある。 (件名にBエンコードを使用する場合の注意点: §.件名にBエンコードを使用したい場合)
SmtpClientクラス
サーバー証明書の検証
SSL接続を有効にする場合、サーバーが自己署名証明書を使用しているなど、サーバー証明書の検証エラーが原因でSmtpExceptionがスローされる場合がある。 以下はMonoでの例。
この場合は、ServicePointManagerクラスにコールバックデリゲートを設定し、サーバー証明書の検証を行うコードを記述する必要がある。
アプリケーション構成ファイルを使った設定
SmtpClientでは、コンストラクタでの指定を省略するとアプリケーション構成ファイルに記述されている内容を読み込んでデフォルト値として使用する。 そのため、構成ファイルを適切に記述しておけばコード上でHost, Port, Credentailsなどのプロパティを指定しなくてもSmtpClientを使用することができるようになる。 (<smtp> 要素 (ネットワーク設定))
コードを書き換えずに使用するSMTPサーバーを変更したい場合などには構成ファイルを使うことができる。 SmtpClientインスタンスを作成したあとプロパティを上書きすれば構成ファイルと異なるサーバーを使用することも出来る。
例としてGMailを使用するようにする場合は、構成ファイルを次のように記述する。
コード上では、コンストラクタに何も指定せずにSmtpClientを作成すれば上記の設定が使用される。
なおnetwork
要素で指定できる属性のうち、enableSsl
のサポートは.NET Framework 4.0以降となっている。 .NET Framework 3.5以前ではenableSsl
を指定しても読み込まれないため、コード上でEnableSslプロパティを設定する必要がある。