MailMessageクラスでハマった のコメント投稿

MailMessageクラスでハマった のコメント投稿を行います
ページ下部のフォーム にコメント情報を入力してください

久々にハマった

.NETでメール送信するときは MailMessage というクラスを部分的に使うのですが、こいつは日本語環境で文字化けしやすいという問題を抱えていました
この問題については "MailMessage 文字化け" などでググると山ほど出てきます

今回はこの問題ではなく .NET Framework 4.5からMailMessageクラスの挙動が変更された ということに起因します

.NET Frameworkの4.0と4.5は共存できない

.NET Frameworkの4.5をインストールすると4.0は勝手にアンインストールされてしまいます
4.5がインストールされているマシンだと、コンパイル時の対象フレームワークに4.0を指定しても実際使用されるのは4.5のアセンブリです

また、Environment.Version を使ってインストールされているVerを判定することはできません(4.5でも “4.0.30319” が返る)。これは、4.5のアセンブリVerが4.0と同じであるためです

インストールされているVerを判定するには

StackOverflow のエラい人によると、下記のようにすればインストールされているVerが4.0以下なのか、4.5以上なのか判定することができるようです

public static bool IsNet45OrNewer() {
    return Type.GetType("System.Reflection.ReflectionContext", false) != null;
}

ReflectionContext クラスは4.5以上にしか存在しないので、4.5以上だと true が返るという塩梅です。スマートですね~

毎回判定してるとパフォーマンスがよろしくないので静的変数に切り出してしまうのが良いでしょう(2つ目のfalseは省略可能です)

public static readonly bool IsNet45OrNewer = 
    Type.GetType("System.Reflection.ReflectionContext") != null;


コード例

// Bエンコード処理
private String BEncode(String text, Encoding encoding) {
    var bytes = encoding.GetBytes(text);
    text = Convert.ToBase64String(bytes);
    return String.Format("=?{0}?B?{1}?=", encoding.HeaderName, text);
}

// メール送信処理
private void SendMail() {
    var encoding = Encoding.GetEncoding("ISO-2022-JP");
    var subject = "件名です";

    if (IsNet45OrNewer) {
        // .NET Framework4.5以上だと二重でBエンコードする
        subject = BEncode(subject, encoding);
    }

    using (var mail = new MailMessage()) {
        mail.Subject = BEncode(subject, encoding);
        // 以降、メール送信処理(ry
    }
}


.NET Frameworkの4.0と4.5は完全互換ではない

今回のケースはまさに↓の記事にあるとおりの内容でした

.NET 4.5で予定されている互換性のない変更

おそらくこのような互換性の問題はかなりレアではあるものの、MailMessageクラスの変更は結構影響が大きそうな気がします

ちなみに MS公式の4.0→4.5の互換性 のページにもMailMessageクラスの変更は載っていません
思ってたよりザルですね…

そもそもMailMessageクラスは日本語環境だと問題が発生しやすいので、Tokiさんが公開されている TKMP というライブラリを使わさせていただくのも手です

※必須入力です。32文字以内のテキストを入力してください
プレビュー
※エディタでHTMLが入力できます(一部の端末ではHTMLエディタが使用できません) ※エディタ内の表示内容は実際のものとは異なります。実際の表示内容はプレビューボタンからプレビューできます ※必須入力です。4000文字以内のテキストを入力してください ※その他の入力内容のルールは こちら で確認できます ※画像は以下のフォームからアップロードできます
画像アップロードフォームを表示
※JPEG、PNG、GIF形式の4MBまでの画像がアップロードできます ※ドラッグ&ドロップでもアップロードできます
アップロード
削除
アップロード画像01
画像をドロップ
アップロード
削除
アップロード画像02
画像をドロップ
アップロード
削除
アップロード画像03
画像をドロップ
アップロード
削除
アップロード画像04
画像をドロップ
アップロード
削除
アップロード画像05
画像をドロップ
アップロード
削除
アップロード画像06
画像をドロップ
アップロード
削除
アップロード画像07
画像をドロップ
アップロード
削除
アップロード画像08
画像をドロップ
認証画像の再読込
※必須入力です。全角ひらがなで構成される4文字のテキストを入力してください ※判読しにくい場合は再読み込みしてください