Postal を使用してMVC Razorビューをレンダリングし、電子メールで送信しています。メールビュー用に特別に定義したカスタムCSSがあります。現在、私はそれらを次のように含めています:
@Styles.Render("~/Content/EmailStyles.css")
ただし、これにはスタイルシートへの相対リンクのみが含まれ、電子メールでは機能しません。
<link href="/Content/EmailStyles.css" rel="stylesheet"/>
電子メールで正しく機能するように、スタイルシートをインラインで含めたいと思います。 MVCビュー内でファイルベースのリソースのコンテンツをレンダリングするための最良の方法は何ですか?
そのためのカスタムヘルパーが必要になると思います。私の頭の上に、ウェブサイトの絶対パスを含むcssパスをレンダリングするそのような方法はありません。
例えばhttp:www.example.com/css/EmailStyles.css
私も同じ質問をして、 Premailer.Net に出くわしました。必要なライブラリのようです。これがあなたがしなければならないことです:
CSSをページに埋め込むのに役立つ拡張メソッドを作成します。 HTMLをRazorビューに埋め込む方法に関する質問への回答 役立つはずです。 CSSを埋め込むために変更しました:
public static class HtmlHelpers
{
public static MvcHtmlString EmbedCss(this HtmlHelper htmlHelper, string path)
{
// take a path that starts with "~" and map it to the filesystem.
var cssFilePath = HttpContext.Current.Server.MapPath(path);
// load the contents of that file
try
{
var cssText = System.IO.File.ReadAllText(cssFilePath);
var styleElement = new TagBuilder("style");
styleElement.InnerHtml = cssText;
return MvcHtmlString.Create(styleElement.ToString());
}
catch (Exception ex)
{
// return nothing if we can't read the file for any reason
return null;
}
}
}
次に、Razorテンプレートで、次の手順を実行します。
@Html.EmbedCss("~/Content/EmailStyles.css")
cSSテキストを埋め込みます。
プロジェクトにPremailer.Netパッケージをインストールします。 NuGetを介して取得できます。
Razorビューを文字列にレンダリングします(これがPostalのプロセスでの目的だと思いますか? RazorEngine でも可能だと思います)。
Premailer.Netを介して文字列を実行します。
PreMailer pm = new PreMailer();
string premailedOutput = pm.MoveCssInline(htmlSource, false);
メールで送ってください!
私はこの手法を本番環境でしばらく使用していますが、非常にうまく機能しているようです。
編集:疑似要素のスタイルインライン化できないマークアップに存在しないため、覚えておいてください。 Premailer.Netの奇妙な小さなバグにも気づきました。それらの特異性とカスケードルールは完全には準拠していないと思います。それでも、それはかなり良いです、そしてそれは私が書く必要がなかったもう一つのコードです!
Paul d'Aoustの答えに賛成しましたが、彼のヘルパーメソッドのこのバージョンは私にとって少しうまく機能することがわかりました(CSSで引用符のようなものをエンコードしようとはしませんでした):
public static class CssHelper
{
public static IHtmlString EmbedCss(this HtmlHelper htmlHelper, string path)
{
// take a path that starts with "~" and map it to the filesystem.
var cssFilePath = HttpContext.Current.Server.MapPath(path);
// load the contents of that file
try
{
var cssText = File.ReadAllText(cssFilePath);
return htmlHelper.Raw("<style>\n" + cssText + "\n</style>");
}
catch
{
// return nothing if we can't read the file for any reason
return null;
}
}
}