web-dev-qa-db-ja.com

RazorビューにCSSスタイルをインラインで含めるにはどうすればよいですか?

Postal を使用してMVC Razorビューをレンダリングし、電子メールで送信しています。メールビュー用に特別に定義したカスタムCSSがあります。現在、私はそれらを次のように含めています:

@Styles.Render("~/Content/EmailStyles.css")

ただし、これにはスタイルシートへの相対リンクのみが含まれ、電子メールでは機能しません。

<link href="/Content/EmailStyles.css" rel="stylesheet"/>

電子メールで正しく機能するように、スタイルシートをインラインで含めたいと思います。 MVCビュー内でファイルベースのリソースのコンテンツをレンダリングするための最良の方法は何ですか?

17
luksan

そのためのカスタムヘルパーが必要になると思います。私の頭の上に、ウェブサイトの絶対パスを含むcssパスをレンダリングするそのような方法はありません。

例えばhttp:www.example.com/css/EmailStyles.css

0
Stay Foolish

私も同じ質問をして、 Premailer.Net に出くわしました。必要なライブラリのようです。これがあなたがしなければならないことです:

  1. 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;
            }
        }
    }
    
  2. 次に、Razorテンプレートで、次の手順を実行します。

    @Html.EmbedCss("~/Content/EmailStyles.css")
    

    cSSテキストを埋め込みます。

  3. プロジェクトにPremailer.Netパッケージをインストールします。 NuGetを介して取得できます。

  4. Razorビューを文字列にレンダリングします(これがPostalのプロセスでの目的だと思いますか? RazorEngine でも可能だと思います)。

  5. Premailer.Netを介して文字列を実行します。

    PreMailer pm = new PreMailer();
    string premailedOutput = pm.MoveCssInline(htmlSource, false);
    
  6. メールで送ってください!

私はこの手法を本番環境でしばらく使用していますが、非常にうまく機能しているようです。

編集:疑似要素のスタイルインライン化できないマークアップに存在しないため、覚えておいてください。 Premailer.Netの奇妙な小さなバグにも気づきました。それらの特異性とカスケードルールは完全には準拠していないと思います。それでも、それはかなり良いです、そしてそれは私が書く必要がなかったもう一つのコードです!

33
Paul d'Aoust

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;
    }
  }
}
9
dprothero