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に含まれているため、ほとんどの場合は参照の追加を行う必要なく使用することができる。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
// メール送信に使用するSMTPサーバー
const string host = "smtp.example.net";
const int port = 25;
using (var client = new SmtpClient(host, port)) {
// 送信者(From)、宛先(To)、件名(Subject)および本文を指定し、
// コンストラクタで指定されたSMTPサーバーを使ってメールを送信する
client.Send("from@example.net", // From
"to@example.net", // To
"Hello!", // Subject
"This is a test mail.");
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
' メール送信に使用するSMTPサーバー
Const host As String = "smtp.example.net"
Const port As Integer = 25
Using client As New SmtpClient(host, port)
' 送信者(From)、宛先(To)、件名(Subject)および本文を指定し、
' コンストラクタで指定されたSMTPサーバーを使ってメールを送信する
client.Send("from@example.net", _
"to@example.net", _
"Hello!", _
"This is a test mail.")
End Using
End Sub
End Class
SMTPサーバーの接続時に認証が必要になる場合はCredentialsプロパティ、SSLでの接続(あるいはSTARTTLS)が必要になる場合はEnableSslプロパティを設定する。 以下はGMail SMTPサーバーを使ってGMailアカウントからメールを送信する例。
using System;
using System.Net;
using System.Net.Mail;
class Sample {
static void Main()
{
// GMail SMTPサーバーを使用するSmtpClientを作成
using (var client = new SmtpClient("smtp.gmail.com", 587)) {
// SSL接続を有効にする
client.EnableSsl = true;
// SMTPサーバーの認証に使用するユーザー名(GMailアカウント名)とパスワードを指定
client.Credentials = new NetworkCredential("user", "pass");
client.Send("user@gmail.com", // From
"to@example.net", // To
"Hello!", // Subject
"This is a test mail.");
}
}
}
Imports System
Imports System.Net
Imports System.Net.Mail
Class Sample
Shared Sub Main()
' GMail SMTPサーバーを使用するSmtpClientを作成
Using client As New SmtpClient("smtp.gmail.com", 587)
' SSL接続を有効にする
client.EnableSsl = True
' SMTPサーバーの認証に使用するユーザー名(GMailアカウント名)とパスワードを指定
client.Credentials = New NetworkCredential("user", "pass")
client.Send("user@gmail.com", _
"to@example.net", _
"Hello!", _
"This is a test mail.")
End Using
End Sub
End Class
MailMessageクラスを使うと、送信するメールの内容を細かく指定することができる。 例えば送信先に複数のメールアドレスを指定したり、ヘッダを設定したりすることができる。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
// MailMessageクラスを使って送信するメールを作成する
var message = new MailMessage();
// 差出人アドレス
message.From = new MailAddress("from@example.net");
// 送信先に3つのメールアドレスを設定する
message.To.Add(new MailAddress("alice@example.net"));
message.To.Add(new MailAddress("bob@example.net"));
message.To.Add(new MailAddress("charlie@example.net"));
// メールの優先度を設定する
message.Priority = MailPriority.High;
// メールの送信日時(Dateヘッダ)を設定する
message.Headers["Date"] = (new DateTime(2001, 2, 3, 4, 56, 7)).ToString("r");
// メールの件名
message.Subject = "Hello!";
// メールの本文
message.Body = "This is a test mail.";
// 作成したメールを送信する
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
' MailMessageクラスを使って送信するメールを作成する
Dim message As New MailMessage()
' 差出人アドレス
message.From = new MailAddress("from@example.net")
' 送信先に3つのメールアドレスを設定する
message.To.Add(New MailAddress("alice@example.net"))
message.To.Add(New MailAddress("bob@example.net"))
message.To.Add(New MailAddress("charlie@example.net"))
' メールの優先度を設定する
message.Priority = MailPriority.High
' メールの送信日時(Dateヘッダ)を設定する
message.Headers("Date") = (New DateTime(2001, 2, 3, 4, 56, 7)).ToString("r")
' メールの件名
message.Subject = "Hello!"
' メールの本文
message.Body = "This is a test mail."
' 作成したメールを送信する
client.Send(message)
End Using
End Sub
End Class
本文や件名に日本語などを使用する方法、文字コードに関する注意点などは後述する。
MailMessageクラス
MailMessageクラスは送信するメールを組み立てるためのクラス。 メールヘッダ・文字コードなどに関する設定や、ファイルの添付を行いたい場合はこのクラスを使ってメールを作成する。
本文の文字コード
本文の文字コードを指定する場合は、BodyEncodingプロパティにEncodingクラスを指定する。 SmtpClientは指定された文字コードを使用して本文をエンコードし、送信する。 この際、UTF-8, UTF-16, UTF-32の場合にはContent-Transfer-Encoding
にBASE64が使用され、それ以外の場合にはquoted-printableが使用される。
using System;
using System.Net.Mail;
using System.Text;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Subject = "こんにちは!";
message.Body = "これはテストメールです。";
message.BodyEncoding = Encoding.UTF8; // 文字コードにUTF-8を使用する
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Text
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Subject = "こんにちは!"
message.Body = "これはテストメールです。"
message.BodyEncoding = Encoding.UTF8 ' 文字コードにUTF-8を使用する
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
44GT44KM44Gv44OG44K544OI44Oh44O844Or44Gn44GZ44CC
From: from@example.net
To: to@example.net
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: quoted-printable
=1B$B$3$l$O%F%9%H%a!<%k$G$9!#=1B(B
件名(Subject)の文字コード
件名(Subject)の文字コードを指定する場合は、本文の場合と同様SubjectEncodingプロパティにEncodingクラスを指定する。 SmtpClientは指定された文字コードを使用して件名をエンコードし、送信する。
.NET Frameworkでは、本文と同様UTF-8, UTF-16, UTF-32の場合にはBASE64(Bエンコード)、それ以外の場合にはquoted-printable(Qエンコード)が使用される。 Mono 3.8時点では、文字コードに関わらず常にquoted-printable(Qエンコード)が使用される模様。
using System;
using System.Net.Mail;
using System.Text;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Subject = "こんにちは!";
message.SubjectEncoding = Encoding.UTF8; // 文字コードにUTF-8を使用する
message.Body = "This is a test mail.";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Text
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Subject = "こんにちは!"
message.SubjectEncoding = Encoding.UTF8 ' 文字コードにUTF-8を使用する
message.Body = "This is a test mail."
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Subject: =?utf-8?B?44GT44KT44Gr44Gh44GvIQ==?=
This is a test mail.
From: from@example.net
To: to@example.net
Subject: =?iso-2022-jp?Q?=1B=24B=243=24s=24K=24A=24O=1B=28B=21?=
This is a test mail.
件名に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エンコードを使用することができる。
using System;
using System.Net.Mail;
using System.Text;
class Sample {
private static string BEncode(string str, Encoding encoding)
{
return string.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)));
}
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
var iso2022jp = Encoding.GetEncoding("iso-2022-jp");
// .NET Framework 4.5以降では、Bエンコードを二回施した文字列を指定する
message.Subject = BEncode(BEncode("こんにちは!", iso2022jp), iso2022jp);
// .NET Framework 4.5より前またはMonoの場合は、Bエンコードを施した文字列を指定するだけでOK
//message.Subject = BEncode("こんにちは!", iso2022jp);
message.Body = "This is a test mail.";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Text
Class Sample
Private Shared Function BEncode(ByVal str As String, ByVal encoding As Encoding) As String
Return String.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)))
End Function
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
Dim iso2022jp As Encoding = Encoding.GetEncoding("iso-2022-jp")
' .NET Framework 4.5以降では、Bエンコードを二回施した文字列を指定する
message.Subject = BEncode(BEncode("こんにちは!", iso2022jp), iso2022jp)
' .NET Framework 4.5より前またはMonoの場合は、Bエンコードを施した文字列を指定するだけでOK
'message.Subject = BEncode("こんにちは!", iso2022jp)
message.Body = "This is a test mail."
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Subject: =?iso-2022-jp?B?GyRCJDMkcyRLJEEkTxsoQiE=?=
This is a test mail.
差出人(From)・宛先(To)・CCなどメールアドレスの表示名と文字コード
メールアドレスを文字列ではなくMailAddressクラスで渡すと、アドレスの表示名(DisplayName)を指定することができる。 表示名の文字コードにはUTF-8が用いられ、Qエンコードされる。
using System;
using System.Net.Mail;
using System.Text;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
// メールアドレスと表示名
var addressFrom = new MailAddress("from@example.net", "差出人");
var addressTo = new MailAddress("to@example.net", "宛先");
// MailAddressを使ってインスタンスを作成
var message = new MailMessage(addressFrom, addressTo);
// MailAddressはCCなどにも使用することができる
message.CC.Add(new MailAddress("cc@example.net", "カーボンコピー"));
message.Subject = "Hello!";
message.Body = "This is a test mail.";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Text
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
' メールアドレスと表示名
Dim addressFrom As New MailAddress("from@example.net", "差出人")
Dim addressTo As New MailAddress("to@example.net", "宛先")
' MailAddressを使ってインスタンスを作成
Dim message As New MailMessage(addressFrom, addressTo)
' MailAddressはCCなどにも使用することができる
message.CC.Add(New MailAddress("cc@example.net", "カーボンコピー"))
message.Subject = "Hello!"
message.Body = "This is a test mail."
client.Send(message)
End Using
End Sub
End Class
From: =?utf-8?Q?=E5=B7=AE=E5=87=BA=E4=BA=BA?= <from@example.net>
To: =?utf-8?Q?=E5=AE=9B=E5=85=88?= <to@example.net>
Cc: =?utf-8?Q?=E3=82=AB=E3=83=BC=E3=83=9C=E3=83=B3=E3=82=B3=E3=83=94=E3?=
=?utf-8?Q?=83=BC?= <cc@example.net>
This is a test mail.
他の文字コードを指定したり、Bエンコードを使用したい場合は、エンコード済みの文字列をDisplayNameに指定すれば、そのまま送信される。
using System;
using System.Net.Mail;
using System.Text;
class Sample {
private static string BEncode(string str, Encoding encoding)
{
return string.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)));
}
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var iso2022jp = Encoding.GetEncoding("iso-2022-jp");
// 表示名にBエンコードした文字列を指定する
var addressFrom = new MailAddress("from@example.net", BEncode("差出人", iso2022jp));
var addressTo = new MailAddress("to@example.net", BEncode("宛先", iso2022jp));
var message = new MailMessage(addressFrom, addressTo);
message.CC.Add(new MailAddress("cc@example.net", BEncode("カーボンコピー", Encoding.UTF8)));
message.Subject = "Hello!";
message.Body = "This is a test mail.";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Text
Class Sample
Private Shared Function BEncode(ByVal str As String, ByVal encoding As Encoding) As String
Return String.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)))
End Function
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim iso2022jp As Encoding = Encoding.GetEncoding("iso-2022-jp")
' 表示名にBエンコードした文字列を指定する
Dim addressFrom As New MailAddress("from@example.net", BEncode("差出人", iso2022jp))
Dim addressTo As New MailAddress("to@example.net", BEncode("宛先", iso2022jp))
Dim message As New MailMessage(addressFrom, addressTo)
message.CC.Add(New MailAddress("cc@example.net", BEncode("カーボンコピー", Encoding.UTF8)))
message.Subject = "Hello!"
message.Body = "This is a test mail."
client.Send(message)
End Using
End Sub
End Class
From: "=?iso-2022-jp?B?GyRCOjk9UD9NGyhC?=" <from@example.net>
To: "=?iso-2022-jp?B?GyRCMDhAaBsoQg==?=" <to@example.net>
Cc: "=?utf-8?B?44Kr44O844Oc44Oz44Kz44OU44O8?=" <cc@example.net>
This is a test mail.
HTMLメールの送信
IsBodyHtmlプロパティをtrue
にすると、Bodyプロパティに設定した内容をHTML(text/html)として送信することができる。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Subject = "Hello!";
message.IsBodyHtml = true;
message.Body = @"<html>
<head>
<title>Hello!</title>
</head>
<body>
<p>This is a <span style=""color: red;"">test</span> mail.</p>
</body>
</html>";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Subject = "Hello!"
message.IsBodyHtml = True
message.Body = "<html>
<head>
<title>Hello!</title>
</head>
<body>
<p>This is a <span style=""color: red;"">test</span> mail.</p>
</body>
</html>"
client.Send(message)
End Using
End Sub
End Class
Subject: Hello!
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: quoted-printable
<html>=0D=0A<head>=0D=0A <title>Hello!</title>=0D=0A</head>=0D=0A=
<body>=0D=0A <p>This is a <span style=3D"color: red;">test</span=
> mail.</p>=0D=0A</body>=0D=0A</html>
ファイルの添付
送信するメールにファイルを添付したい場合はAttachmentクラスを使用する。 添付したいファイルごとにAttachmentを作成し、Attachmentsプロパティに追加する。
using System;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Subject = "Hello!";
message.Body = "This is a test mail.";
// ファイル"thumbnail.jpg"から添付ファイルを作成する
var attach1 = new Attachment("thumbnail.jpg", MediaTypeNames.Image.Jpeg);
// 添付ファイルの名称(メールクライアント上で表示される名称)を設定する
// (オリジナルのファイル名をそのまま使用する場合は設定しなくてもよい)
attach1.Name = "サムネイル.jpg";
attach1.NameEncoding = Encoding.UTF8;
attach1.ContentDisposition.Inline = true; // 添付した画像をインライン表示する
// ファイル"image.jpg"から添付ファイルを作成する
var attach2 = new Attachment("image.jpg", MediaTypeNames.Image.Jpeg);
attach2.Name = "写真.jpg";
attach2.NameEncoding = Encoding.UTF8;
// ファイル"files.zip"から添付ファイルを作成する
var attach3 = new Attachment("files.zip", MediaTypeNames.Application.Zip);
// 作成した添付ファイルをメールに追加する
message.Attachments.Add(attach1);
message.Attachments.Add(attach2);
message.Attachments.Add(attach3);
// 作成したメールを送信する
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Net.Mime
Imports System.Text
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Subject = "Hello!"
message.Body = "This is a test mail."
' ファイル"thumbnail.jpg"から添付ファイルを作成する
Dim attach1 As New Attachment("thumbnail.jpg", MediaTypeNames.Image.Jpeg)
' 添付ファイルの名称(メールクライアント上で表示される名称)を設定する
' (オリジナルのファイル名をそのまま使用する場合は設定しなくてもよい)
attach1.Name = "サムネイル.jpg"
attach1.NameEncoding = Encoding.UTF8
attach1.ContentDisposition.Inline = True ' 添付した画像をインライン表示する
' ファイル"image.jpg"から添付ファイルを作成する
Dim attach2 As New Attachment("image.jpg", MediaTypeNames.Image.Jpeg)
attach2.Name = "写真.jpg"
attach2.NameEncoding = Encoding.UTF8
' ファイル"files.zip"から添付ファイルを作成する
Dim attach3 As New Attachment("files.zip", MediaTypeNames.Application.Zip)
' 作成した添付ファイルをメールに追加する
message.Attachments.Add(attach1)
message.Attachments.Add(attach2)
message.Attachments.Add(attach3)
' 作成したメールを送信する
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.jp
Subject: Hello!
Content-Type: multipart/mixed;
boundary=--boundary_0_8cf3cbdb-6a8b-45fa-a6e2-9fa6e86b1419
----boundary_0_8cf3cbdb-6a8b-45fa-a6e2-9fa6e86b1419
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable
This is a test mail.
----boundary_0_8cf3cbdb-6a8b-45fa-a6e2-9fa6e86b1419
Content-Type: image/jpeg; name="=?utf-8?B?44K144Og44ON44Kk44OrLmpwZw==?="
Content-Transfer-Encoding: base64
Content-Disposition: inline
/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAMCAgMCAgMDAwME
AwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBD
:
:
AAAAAAAAAID/2gAIAQEAAT8QFn//2Q==
----boundary_0_8cf3cbdb-6a8b-45fa-a6e2-9fa6e86b1419
Content-Type: image/jpeg; name="=?utf-8?B?5YaZ55yfLmpwZw==?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment
/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAMCAgMCAgMDAwME
AwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBD
:
:
xAAUEAEAAAAAAAAAAAAAAAAAAADA/9oACAEBAAE/EBYH/9k=
----boundary_0_8cf3cbdb-6a8b-45fa-a6e2-9fa6e86b1419
Content-Type: application/zip; name=files.zip
Content-Transfer-Encoding: base64
Content-Disposition: attachment
UEsDBBQAAAAIACa2QUUj5UOEDQEAAD8XAAAJABwAaW1hZ2UuanBnVVQJAANXBixURgYsVHV4CwAB
BOgDAAAE6AMAAO2XT0oDMRSH30smM+kkMyZtMnZZTzKLQm0FwSsIFnQrBZd6BA/gYaR4CP9suvYQ
:
:
AFBLBQYAAAAAAgACAKIAAACPAgAAAAA=
----boundary_0_8cf3cbdb-6a8b-45fa-a6e2-9fa6e86b1419--
Mono 3.8の時点では、Attachment.ContentDispositionのFileNameプロパティを設定していなくてもContent-Disposition
ヘッダにfilename
パラメータが設定されるが、その内容が正しくエンコードされないため注意が必要。
From: from@example.net
To: to@example.net
Subject: Hello!
Content-Type: multipart/mixed; boundary=--boundary_0_38305959-29ce-476a-919d-f1b701c7d52a
----boundary_0_38305959-29ce-476a-919d-f1b701c7d52a
content-type: text/plain; charset=us-ascii
content-transfer-encoding: 7bit
This is a test mail.
----boundary_0_38305959-29ce-476a-919d-f1b701c7d52a
content-type: image/jpeg; charset=utf-8; name="=?utf-8?Q?=E3=82=B5=E3=83=A0=E3=83=8D=E3=82=A4=E3=83=AB.jpg?="
content-transfer-encoding: base64
content-disposition: inline; filename=繧オ繝繝阪う繝ォ.jpg
:
:
関連: MIMEタイプの取得・判定
ヘッダの長さと折り返し
SubjectプロパティやHeadersプロパティでヘッダの内容を指定する場合、長さは特に制限されない上、ヘッダの折り返しもされない模様。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Body = "This is a test mail.";
// 件名に360文字の'x'を指定して送信する
message.Subject = new string('x', 360);
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Body = "This is a test mail."
' 件名に360文字の'x'を指定して送信する
message.Subject = New String("x"c, 360)
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Subject: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: text/plain; charset=us-ascii
This is a test mail.
.NET Frameworkでは半角空白が含まれている個所で自動的に折り返しが行われる。 一方Monoではこの場合も折り返されずにそのまま送信される。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Body = "This is a test mail.";
message.Subject =
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx " +
"xxxxxxxxxx";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Body = "This is a test mail."
message.Subject = _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx " + _
"xxxxxxxxxx"
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Subject: xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx
xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx
Content-Type: text/plain; charset=us-ascii
This is a test mail.
From: from@example.net
To: to@example.net
Subject: xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx
Content-Type: text/plain; charset=us-ascii
This is a test mail.
また、Subjectプロパティに設定する文字列に改行とタブを含めることによって強制的にヘッダの折り返しを行わせる方法については、.NET FrameworkではArgumentExceptionとなるため使用できない。 一方Monoではこの方法によってヘッダの折り返しを行うことができる。
SubjectプロパティではなくHeadersプロパティを使ってヘッダに直接値を設定することもできるが、この方法はMonoのみで使用できる。 .NET Frameworkの場合、Headersプロパティを使って値を設定してもSubjectヘッダには反映されない(Subjectヘッダが設定されず、件名が空になる)。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Body = "This is a test mail.";
// .NET Frameworkでは件名に改行文字やタブを含めようとするとArgumentExceptionがスローされる
// Monoでは折り返されたヘッダが送信される
message.Subject = "aaa\r\n\tbbb\r\n\tccc";
message.Subject = "aaa\r\n bbb\r\n ccc";
message.Subject = "aaa\n bbb\n ccc";
// .NET Frameworkでは値が反映されず、Subjectヘッダが設定されない
// Monoでは折り返されたヘッダが送信される
message.Headers["Subject"] = "aaa\r\n\tbbb\r\n\tccc";
message.Headers["Subject"] = "aaa\r\n bbb\r\n ccc";
message.Headers["Subject"] = "aaa\n bbb\n ccc";
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Body = "This is a test mail."
' .NET Frameworkでは件名に改行文字やタブを含めようとするとArgumentExceptionがスローされる
' Monoでは折り返されたヘッダが送信される
message.Subject = "aaa" + vbCrLf + vbTab + "bbb" + vbCrLf + vbTab + "ccc"
message.Subject = "aaa" + vbCrLf + " " + "bbb" + vbCrLf + " " + "ccc"
message.Subject = "aaa" + vbLf + " " + "bbb" + vbLf + " " + "ccc"
' .NET Frameworkでは値が反映されず、Subjectヘッダが設定されない
' Monoでは折り返されたヘッダが送信される
message.Headers("Subject") = "aaa" + vbCrLf + vbTab + "bbb" + vbCrLf + vbTab + "ccc"
message.Headers("Subject") = "aaa" + vbCrLf + " " + "bbb" + vbCrLf + " " + "ccc"
message.Headers("Subject") = "aaa" + vbLf + " " + "bbb" + vbLf + " " + "ccc"
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Content-Type: text/plain; charset=us-ascii
This is a test mail.
From: from@example.net
To: to@example.net
Subject: aaa
bbb
ccc
Content-Type: text/plain; charset=us-ascii
This is a test mail.
ヘッダの折り返しではなく改行文字そのものを件名に含めたい場合などは、Bエンコード(あるいはQエンコード)した文字列を設定する必要がある。 (件名にBエンコードを使用する場合の注意点: §.件名にBエンコードを使用したい場合)
using System;
using System.Net.Mail;
using System.Text;
class Sample {
private static string BEncode(string str, Encoding encoding)
{
return string.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)));
}
static void Main()
{
using (var client = new SmtpClient("smtp.example.net", 25)) {
var message = new MailMessage("from@example.net", "to@example.net");
message.Body = "This is a test mail.";
// Bエンコードして件名に改行を含む文字列を設定する
message.Subject = BEncode("こんにちは!\r\nこんにちは!", Encoding.GetEncoding("iso-2022-jp"));
client.Send(message);
}
}
}
Imports System
Imports System.Net.Mail
Imports System.Text
Class Sample
Private Shared Function BEncode(ByVal str As String, ByVal encoding As Encoding) As String
Return String.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)))
End Function
Shared Sub Main()
Using client As New SmtpClient("smtp.example.net", 25)
Dim message As New MailMessage("from@example.net", "to@example.net")
message.Body = "This is a test mail."
' Bエンコードして件名に改行を含む文字列を設定する
message.Subject = BEncode("こんにちは!" + vbCrLf + "こんにちは!", Encoding.GetEncoding("iso-2022-jp"))
client.Send(message)
End Using
End Sub
End Class
From: from@example.net
To: to@example.net
Subject: =?iso-2022-jp?B?GyRCJDMkcyRLJEEkTxsoQiENChskQiQzJHMkSyRBJE8bKEIh?=
Content-Type: text/plain; charset=us-ascii
This is a test mail.
SmtpClientクラス
サーバー証明書の検証
SSL接続を有効にする場合、サーバーが自己署名証明書を使用しているなど、サーバー証明書の検証エラーが原因でSmtpExceptionがスローされる場合がある。 以下はMonoでの例。
Unhandled Exception: System.Net.Mail.SmtpException: Message could not be sent. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.InvalidOperationException: SSL authentication error: RemoteCertificateNotAvailable, RemoteCertificateChainErrors
この場合は、ServicePointManagerクラスにコールバックデリゲートを設定し、サーバー証明書の検証を行うコードを記述する必要がある。
using System;
using System.Net;
using System.Net.Mail;
class Sample {
static void Main()
{
// サーバー証明書の検証を省略し、エラーがあっても証明書を受け付ける
// (接続先が信頼できる場合を除き、適切な検証を行うべき)
ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
using (var client = new SmtpClient("smtp.example.net", 587)) {
// SSL接続を有効にする
client.EnableSsl = true;
// SMTPサーバーの認証に使用するユーザー名とパスワードを指定
client.Credentials = new NetworkCredential("from", "pass");
client.Send("from@example.net", // From
"to@example.net", // To
"Hello!", // Subject
"This is a test mail.");
}
}
}
Imports System
Imports System.Net
Imports System.Net.Mail
Imports System.Net.Security
Imports System.Security.Cryptography.X509Certificates
Class Sample
Private Shared Function ValidateRemoteCertificate(ByVal sender As Object, _
ByVal certificate As X509Certificate, _
ByVal chain As X509Chain, _
ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
' サーバー証明書の検証を省略し、エラーがあっても証明書を受け付ける
' (接続先が信頼できる場合を除き、適切な検証を行うべき)
Return True
End Function
Shared Sub Main()
ServicePointManager.ServerCertificateValidationCallback = AddressOf ValidateRemoteCertificate
Using client As New SmtpClient("smtp.example.net", 587)
' SSL接続を有効にする
client.EnableSsl = True
' SMTPサーバーの認証に使用するユーザー名とパスワードを指定
client.Credentials = New NetworkCredential("from", "pass")
client.Send("from@example.net", _
"to@example.net", _
"Hello!", _
"This is a test mail.")
End Using
End Sub
End Class
アプリケーション構成ファイルを使った設定
SmtpClientでは、コンストラクタでの指定を省略するとアプリケーション構成ファイルに記述されている内容を読み込んでデフォルト値として使用する。 そのため、構成ファイルを適切に記述しておけばコード上でHost, Port, Credentailsなどのプロパティを指定しなくてもSmtpClientを使用することができるようになる。 (<smtp> 要素 (ネットワーク設定))
コードを書き換えずに使用するSMTPサーバーを変更したい場合などには構成ファイルを使うことができる。 SmtpClientインスタンスを作成したあとプロパティを上書きすれば構成ファイルと異なるサーバーを使用することも出来る。
例としてGMailを使用するようにする場合は、構成ファイルを次のように記述する。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod="network">
<!-- GMail -->
<network
host = "smtp.gmail.com"
port = "587"
enableSsl = "true"
userName = "user"
password = "pass"
/>
</smtp>
</mailSettings>
</system.net>
</configuration>
コード上では、コンストラクタに何も指定せずにSmtpClientを作成すれば上記の設定が使用される。
using System;
using System.Net.Mail;
class Sample {
static void Main()
{
// 構成ファイルに記述されている設定を使用してSmtpClientを作成する
using (var client = new SmtpClient()) {
// メールを送信する
client.Send("user@gmail.com", // From
"to@example.net", // To
"Hello!", // Subject
"This is a test mail.");
}
}
}
Imports System
Imports System.Net.Mail
Class Sample
Shared Sub Main()
' 構成ファイルに記述されている設定を使用してSmtpClientを作成する
Using client As New SmtpClient()
' メールを送信する
client.Send("user@gmail.com", _
"to@example.net", _
"Hello!", _
"This is a test mail.")
End Using
End Sub
End Class
なおnetwork
要素で指定できる属性のうち、enableSsl
のサポートは.NET Framework 4.0以降となっている。 .NET Framework 3.5以前ではenableSsl
を指定しても読み込まれないため、コード上でEnableSslプロパティを設定する必要がある。