2014-10-02T01:38:29の更新内容

programming/netfx/tips/send_mail/index.wiki.txt

current previous
1,754 1,94
~
${smdncms:title,メールの送信}
${smdncms:title,System.Net.Mail.SmtpClient}
~
${smdncms:header_title,メールの送信 (SmtpClient, MailMessage)}
${smdncms:keywords,System.Net.Mail,SmtpClient,MailMessage}
+
${smdncms:keywords,System.Net.Mail,SmtpClient,MailMessage,メール,送信,添付ファイル}
 

        

        
~
&msdn(netfx,type,System.Net.Mail.SmtpClient){System.Net.Mail.SmtpClientクラス};、&msdn(netfx,type,System.Net.Mail.MailMessage){System.Net.Mail.MailMessageクラス};を使ったメールの送信方法、メール作成時の注意点など。
System.Net.Mail.SmtpClientの使い方、メールの送信方法など。
 

        

        
 
-関連するページ
-関連するページ
+
--[[programming/netfx/tips/receive_mail_imap]]
+
--[[programming/netfx/tips/receive_mail_pop]]
 
--[[programming/netfx/tips/find_mimetype]]
--[[programming/netfx/tips/find_mimetype]]
 
--[[programming/netfx/tips/quoted_printable]]
--[[programming/netfx/tips/quoted_printable]]
 
--[[programming/netfx/tips/compute_md5sum]]
--[[programming/netfx/tips/compute_md5sum]]
+
--[[programming/netfx/text_format_conversion]]
+
--[[programming/netfx/tips/find_mimetype]]
+

          
+
以下の内容は主に.NET Framework 4以降を対象としている。 サンプルコードは.NET Framework 4.5およびMono 3.8で動作検証済み。
 

        

        
 
#adunit
#adunit
 

        

        
-
*SmtpClientとMailMessageの使い方
-
**基本・メールを送信する
-
本文・ヘッダともにiso-2022-jpを使用してメールを送信する例。 コメントにあるように、ヘッダのエンコーディングにiso-2022-jpなどを指定しても正しいQエンコーディング文字列にはならないので、代わりに自前でBエンコードするようにする。
 

        

        
~
*メールの送信
#code(cs){{
~
SMTPサーバーのホスト名とポート番号を指定してSmtpClientのインスタンスを作成し、&msdn(netfx,member,System.Net.Mail.SmtpClient.Send){Sendメソッド};を呼び出すことで指定した宛先にメールを送ることができる。
private static string GetBEncoded(string str, Encoding encoding)
~

          
{
~
SmtpClient(System.Net.Mail名前空間)はSystem.dllに含まれているため、ほとんどの場合は参照の追加を行う必要なく使用することができる。
  return string.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)));
+

          
+
#code(cs,SmtpClientを使ったメールの送信){{
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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.");
+
    }
+
  }
+
}
+
}}
+

          
+
SMTPサーバーの接続時に認証が必要になる場合は&msdn(netfx,member,System.Net.Mail.SmtpClient.Credentials){Credentialsプロパティ};、SSLでの接続(あるいはSTARTTLS)が必要になる場合は&msdn(netfx,member,System.Net.Mail.SmtpClient.EnableSsl){EnableSslプロパティ};を設定する。 以下はGMail SMTPサーバーを使ってGMailアカウントからメールを送信する例。
+

          
+
#code(cs,GMailアカウントを使ってメールを送信する例){{
+
using System;
+
using System.Net;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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.");
+
    }
+
  }
 
}
}
+
}}
+

          
+
&msdn(netfx,type,System.Net.Mail.MailMessage){MailMessageクラス};を使うと、送信するメールの内容を細かく指定することができる。 例えば送信先に複数のメールアドレスを指定したり、ヘッダを設定したりすることができる。
+

          
+
#code(cs,MailMessageクラスを使ってメールを作成・送信する例){{
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
+

          
+
本文や件名に日本語などを使用する方法、文字コードに関する注意点などは後述する。
+

          
+

          
+

          
+
*MailMessageクラス [#MailMessage]
+
MailMessageクラスは送信するメールを組み立てるためのクラス。 メールヘッダ・文字コードなどに関する設定や、ファイルの添付を行いたい場合はこのクラスを使ってメールを作成する。
 

        

        
~
**本文の文字コード [#MailMessage_BodyEncoding]
public static void Main()
~
本文の文字コードを指定する場合は、&msdn(netfx,member,System.Net.Mail.MailMessage.BodyEncoding){BodyEncodingプロパティ};に&msdn(netfx,type,System.Text.Encoding){Encodingクラス};を指定する。 SmtpClientは指定された文字コードを使用して本文をエンコードし、送信する。 この際、UTF-8, UTF-16, UTF-32の場合には``Content-Transfer-Encoding``にBASE64が使用され、それ以外の場合にはquoted-printableが使用される。
{
-
  var message = new MailMessage("from@mail.example.com", "to@mail.example.net");
 

        

        
~
#code(cs){{
  message.Body = "本文";
~
using System;
  message.BodyEncoding = Encoding.GetEncoding("iso-2022-jp");
+
using System.Net.Mail;
+
using System.Text;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
 

        

        
~
#code(,送信されるメールの内容(BodyEncodingにUTF-8を指定した場合、抜粋)){{
  /*
~
From: from@example.net
   * http://support.microsoft.com/kb/933866/ja
~
To: to@example.net
   * NET Framework 2.0 ベースのアプリケーションで MailMessage を使ってメッセージを送信すると送受信者名、件名が文字化けする
~
Content-Type: text/plain; charset=utf-8
   */
~
Content-Transfer-Encoding: base64
  message.Subject = GetBEncoded("件名", Encoding.GetEncoding("iso-2022-jp"));
+

          
+
44GT44KM44Gv44OG44K544OI44Oh44O844Or44Gn44GZ44CC
+
}}
 

        

        
~
#code(,送信されるメールの内容(BodyEncodingにiso-2022-jpを指定した場合、抜粋)){{
  var client = new SmtpClient("localhost", 25);
+
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
  client.Send(message);
 
}}
}}
 

        

        
~

          
**ヘッダの長さと折り返し
~
**件名(Subject)の文字コード [#MailMessage_SubjectEncoding]
SubjectプロパティやHeadersプロパティでヘッダの内容を指定する場合、長さなどは制限されない上、折り返しもされない模様。
+
件名(Subject)の文字コードを指定する場合は、本文の場合と同様&msdn(netfx,member,System.Net.Mail.MailMessage.SubjectEncoding){SubjectEncodingプロパティ};に&msdn(netfx,type,System.Text.Encoding){Encodingクラス};を指定する。 SmtpClientは指定された文字コードを使用して件名をエンコードし、送信する。
+

          
+
.NET Frameworkでは、本文と同様UTF-8, UTF-16, UTF-32の場合にはBASE64(Bエンコード)、それ以外の場合にはquoted-printable(Qエンコード)が使用される。 Mono 3.8時点では、文字コードに関わらず常にquoted-printable(Qエンコード)が使用される模様。
+

          
 
#code(cs){{
#code(cs){{
~
using System;
var message = new MailMessage(...);
+
using System.Net.Mail;
+
using System.Text;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(,送信されるメールの内容(SubjectEncodingにUTF-8を指定した場合、抜粋)){{
+
From: from@example.net
+
To: to@example.net
+
Subject: =?utf-8?B?44GT44KT44Gr44Gh44GvIQ==?=
 

        

        
~
This is a test mail.
// 送信されるメッセージのSubjectヘッダには360文字のxが折り返されずに指定される
-
message.Subject = new string('x', 360);
 
}}
}}
 

        

        
~

          
また、改行やタブなどを含む文字列を指定することもできないので、無理矢理折り返させることも出来ない。
+
#code(,送信されるメールの内容(SubjectEncodingにiso-2022-jpを指定した場合、抜粋)){{
+
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エンコードを使用したい場合 [#MailMessage_SubjectEncoding_BEncoding]
+
件名に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エンコードを使用することができる。
+

          
 
#code(cs){{
#code(cs){{
~
using System;
message.Subject = "line1\r\n\tline2\r\n\tline3";  // ArgumentException
~
using System.Net.Mail;
message.Subject = "line1\r\n line2\r\n line3";    // ArgumentException
~
using System.Text;
message.Subject = "line1\n line2\n line3";        // ArgumentException
~

          
message.Headers["Subject"] = "line1\r\n\tline2\r\n\tline3"; // FormatException
~
class Sample {
message.Headers["Subject"] = "line1\r\n line2\r\n line3";   // FormatException
~
  private static string BEncode(string str, Encoding encoding)
message.Headers["Subject"] = "line1\n line2\n line3";       // FormatException
+
  {
+
    return string.Format("=?{0}?B?{1}?=", encoding.HeaderName, Convert.ToBase64String(encoding.GetBytes(str)));
+
  }
+

          
+
  public 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);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(,送信されるメールの内容(抜粋)){{
+
From: from@example.net
+
To: to@example.net
+
Subject: =?iso-2022-jp?B?GyRCJDMkcyRLJEEkTxsoQiE=?=
+

          
+
This is a test mail.
+
}}
+

          
+

          
+
-参考
+
--[[.NET Framework 4.5 の System.Net.Mail で日本語の件名を ISO-2022-JP の Base64 でエンコードして送信する方法:http://blogs.technet.com/b/exchangeteamjp/archive/2012/10/05/3524293.aspx]] (Exchange ブログ JAPAN)
+
-関連
+
--[[.NET Framework 2.0 ベースのアプリケーションで MailMessage を使ってメッセージを送信すると送受信者名、件名が文字化けする:http://support.microsoft.com/kb/933866/ja]]
+

          
+

          
+
**差出人(From)・宛先(To)・CCなどメールアドレスの表示名と文字コード [#MailMessage_MailAddressDisplayNameEncoding]
+
メールアドレスを文字列ではなく&msdn(netfx,type,System.Net.Mail.MailAddress){MailAddressクラス};で渡すと、アドレスの表示名(DisplayName)を指定することができる。 表示名の文字コードにはUTF-8が用いられ、Qエンコードされる。
+

          
+
#code(cs,アドレスに表示名を付けてメールを送信する例){{
+
using System;
+
using System.Net.Mail;
+
using System.Text;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
 
}}
}}
 

        

        
~
#code(,送信されるメールの内容(抜粋)){{
*SmtpClientインスタンスの作成
~
From: =?utf-8?Q?=E5=B7=AE=E5=87=BA=E4=BA=BA?= <from@example.net>
**SMTPサーバとしてGMailを使用する
~
To: =?utf-8?Q?=E5=AE=9B=E5=85=88?= <to@example.net>
GMail SMTPサーバでは認証とSSLでの接続が必要になるため、CredentialsとEnableSsl設定する必要がある。
+
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に指定すれば、そのまま送信される。
+

          
+
#code(cs,表示名を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)));
+
  }
+

          
+
  public 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);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(,送信されるメールの内容(抜粋)){{
+
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メールの送信 [#MailMessage_HTMLMail]
+
&msdn(netfx,member,System.Net.Mail.MailMessage.IsBodyHtml){IsBodyHtmlプロパティ};を``true``にすると、Bodyプロパティに設定した内容をHTML(text/html)として送信することができる。
+

          
+
#code(cs,HTMLメールを送信する例){{
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    using (var client = new SmtpClient("localhost", 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);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(,送信されるメールの内容(抜粋)){{
+
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>
+
}}
+

          
+

          
+
**ファイルの添付 [#MailMessage_Attachments]
+
送信するメールにファイルを添付したい場合は&msdn(netfx,type,System.Net.Mail.Attachment){Attachmentクラス};を使用する。 添付したいファイルごとにAttachmentを作成し、&msdn(netfx,member,System.Net.Mail.MailMessage.Attachments){Attachmentsプロパティ};に追加する。
+

          
 
#code(cs){{
#code(cs){{
~
using System;
/*
~
using System.Net.Mail;
 * 前略
~
using System.Net.Mime;
 */
+
using System.Text;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(,送信されるメールの内容(抜粋)){{
+
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の時点では、&msdn(netfx,member,System.Net.Mail.Attachment.ContentDisposition){Attachment.ContentDisposition};の&msdn(netfx,member,System.Net.Mime.ContentDisposition.FileName){FileNameプロパティ};を設定していなくても``Content-Disposition``ヘッダに``filename``パラメータが設定されるが、その内容が正しくエンコードされないため注意が必要。
+

          
+
#code(cs,送信されるメールの内容(Mono 3.8の場合、抜粋)){{
+
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
+

          
+
  :
+
  :
+
}}
+

          
+
-関連: [[programming/netfx/tips/find_mimetype]]
+

          
+

          
+
**ヘッダの長さと折り返し [#MailMessage_HeaderFolding]
+
SubjectプロパティやHeadersプロパティでヘッダの内容を指定する場合、長さは特に制限されない上、ヘッダの折り返しもされない模様。
+

          
+
#code(cs,Subjectヘッダに長い文字列を指定する例){{
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(,送信されるメールの内容(抜粋)){{
+
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ではこの場合も折り返されずにそのまま送信される。
+

          
+
#code(cs,Subjectヘッダに半角空白を含む長い文字列を指定する例){{
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
 

        

        
~
#code(,送信されるメールの内容(.NET Framework 4.5の場合、抜粋)){{
var client = new SmtpClient("smtp.gmail.com", 587);
+
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.
client.DeliveryMethod = SmtpDeliveryMethod.Network;
~
}}
client.Credentials = new NetworkCredential("user", "pass");
~

          
client.EnableSsl = true;
+
#code(,送信されるメールの内容(Mono 3.8の場合、抜粋)){{
+
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ヘッダが設定されず、件名が空になる)。
+

          
+
#code(cs,Subjectヘッダの折り返しを行う例){{
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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);
+
    }
+
  }
+
}
+
}}
 

        

        
~
#code(,送信されるメールの内容(.NET FrameworkでHeadersプロパティを設定した場合、抜粋)){{
client.Send(message);
+
From: from@example.net
+
To: to@example.net
+
Content-Type: text/plain; charset=us-ascii
+

          
+
This is a test mail.
+
}}
+

          
+

          
+
#code(,送信されるメールの内容(Monoの場合、抜粋)){{
+
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エンコードを使用する場合の注意点: [[#MailMessage_SubjectEncoding_BEncoding]])
+

          
+
#code(cs,Subjectヘッダに改行を含む文字列を設定する例){{
+
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)));
+
  }
+

          
+
  public 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);
+
    }
+
  }
+
}
 
}}
}}
 

        

        
~
#code(,送信されるメールの内容(抜粋)){{
**SMTPサーバの設定にアプリケーション構成ファイルを使用する
~
From: from@example.net
SmtpClientのHost, Port, Credentailsなどのプロパティは、コンストラクタ等で明示的に指定しない場合、アプリケーション構成ファイルから設定が読み込まれる。 SMTPサーバが不変の場合などは、アプリケーション構成ファイルを使うことができる。
+
To: to@example.net
+
Subject: =?iso-2022-jp?B?GyRCJDMkcyRLJEEkTxsoQiENChskQiQzJHMkSyRBJE8bKEIh?=
+
Content-Type: text/plain; charset=us-ascii
+

          
+
This is a test mail.
+
}}
+

          
+

          
+

          
+
*SmtpClientクラス [#SmtpClient]
+
**サーバー証明書の検証 [#SmtpClient_ServerCertificateValidation]
+
SSL接続を有効にする場合、サーバーが自己署名証明書を使用しているなど、サーバー証明書の検証エラーが原因で&msdn(netfx,type,System.Net.Mail.SmtpException){SmtpException};がスローされる場合がある。 以下はMonoでの例。
+

          
+
#prompt{{
+
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
+
}}
+

          
+
この場合は、&msdn(netfx,type,System.Net.ServicePointManager){ServicePointManagerクラス};にコールバックデリゲートを設定し、サーバー証明書の検証を行うコードを記述する必要がある。
+

          
+
#code(cs,サーバー証明書の検証を行うコールバックデリゲートを設定する例){{
+
using System;
+
using System.Net;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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.");
+
    }
+
  }
+
}
+
}}
+

          
+
**アプリケーション構成ファイルを使った設定 [#SmtpClient_AppConfig]
+
SmtpClientでは、コンストラクタでの指定を省略するとアプリケーション構成ファイルに記述されている内容を読み込んでデフォルト値として使用する。 そのため、構成ファイルを適切に記述しておけばコード上でHost, Port, Credentailsなどのプロパティを指定しなくてもSmtpClientを使用することができるようになる。 (&msdn(netfx,id,ms164240){<smtp> 要素 (ネットワーク設定)};)
+

          
+
コードを書き換えずに使用するSMTPサーバーを変更したい場合などには構成ファイルを使うことができる。 SmtpClientインスタンスを作成したあとプロパティを上書きすれば構成ファイルと異なるサーバーを使用することも出来る。
+

          
+
例としてGMailを使用するようにする場合は、構成ファイルを次のように記述する。
 

        

        
-
前項のGMailを使用する場合の例をアプリケーション構成ファイルを使って記述すると次のようになる。
 
#code(xml,test.exe.config){{
#code(xml,test.exe.config){{
 
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
 
<configuration>
<configuration>
 
  <system.net>
  <system.net>
 
    <mailSettings>
    <mailSettings>
 
      <smtp deliveryMethod="network">
      <smtp deliveryMethod="network">
+
        <!-- GMail -->
 
        <network
        <network
~
          host      = "smtp.gmail.com"
          host     = "smtp.gmail.com"
~
          port      = "587"
          port     = "587"
~
          enableSsl = "true"
          userName = "user"
~
          userName  = "user"
          password = "pass"
+
          password  = "pass"
 
        />
        />
 
      </smtp>
      </smtp>
 
    </mailSettings>
    </mailSettings>
756,28 96,18
 
</configuration>
</configuration>
 
}}
}}
 

        

        
~
コード上では、コンストラクタに何も指定せずにSmtpClientを作成すれば上記の設定が使用される。
ただし、EnableSslプロパティはアプリケーション構成ファイルでは指定できないので、コード中で指定するほかない。
-
#code(cs){{
-
/*
-
 * 前略
-
 */
 

        

        
~
#code(cs,text.exe){{
var client = new SmtpClient();
+
using System;
+
using System.Net.Mail;
+

          
+
class Sample {
+
  public 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.");
+
    }
+
  }
+
}
+
}}
 

        

        
~
なお``network``要素で指定できる属性のうち、``enableSsl``のサポートは.NET Framework 4.0以降となっている。 .NET Framework 3.5以前では``enableSsl``を指定しても読み込まれないため、コード上でEnableSslプロパティを設定する必要がある。
client.EnableSsl = true;
 

        

        
-
client.Send(message);
-
}}
 

        

        
-
.NET Framework 4からはアプリケーション構成ファイルで指定できる項目が増え、EnableSslプロパティに相当する属性も指定出来るようになる模様。