如何在Razor视图中包含内联CSS样式?

luk*_*san 16 asp.net-mvc razor asp.net-mvc-4 postal

我使用Postal来呈现MVC Razor视图并通过电子邮件发送它们.我有一个我专门为电子邮件视图定义的自定义CSS.目前我将它们包括在内如下:

@Styles.Render("~/Content/EmailStyles.css")
Run Code Online (Sandbox Code Playgroud)

但是,这仅包括样式表的相对链接,这在电子邮件中不起作用:

<link href="/Content/EmailStyles.css" rel="stylesheet"/>
Run Code Online (Sandbox Code Playgroud)

我希望将样式表内联,以便它在电子邮件中正常运行.在MVC视图中呈现基于文件的资源的内容的最佳方法是什么?

Pau*_*ust 33

我自己也有同样的问题,并遇到了Premailer.Net.它看起来像你需要的库.这是你必须做的事情:

  1. 创建一个扩展方法,以帮助您将CSS嵌入到您的页面中; 关于如何在Razor视图嵌入HTML以帮助您的问题,我们一个答案.我已经修改它以嵌入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;
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后在你的Razor模板中,只需:

    @Html.EmbedCss("~/Content/EmailStyles.css")
    
    Run Code Online (Sandbox Code Playgroud)

    嵌入CSS文本.

  3. 在项目中安装Premailer.Net包; 你可以通过NuGet获得它.

  4. 将你的Razor视图渲染成一个字符串(我猜这是你的过程中的邮政?我相信RazorEngine也可以这样做).

  5. 通过Premailer.Net运行字符串:

    PreMailer pm = new PreMailer();
    string premailedOutput = pm.MoveCssInline(htmlSource, false);
    
    Run Code Online (Sandbox Code Playgroud)
  6. 发送电子邮件!

我一直在生产中使用这种技术已经有一段时间了,它似乎运作得很好.

编辑:请记住,伪元素上的样式无法内联,因为它们在标记中不存在.我也注意到Premailer.Net中的奇怪小错误 - 我认为它们的特异性和级联规则并不完全一致.不过,它还是相当不错的,而且还有一段我不需要编写的代码!


dpr*_*ero 9

赞成了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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*ish 1

我想你需要一个自定义助手来做到这一点。在我的脑海中,没有这样的方法来渲染CSS路径,包括网站的绝对路径。

例如http:www.example.com/css/EmailStyles.css

  • 是的,但我什至不想包含样式表的绝对路径,因为出于安全原因电子邮件客户端不会检索它。我想包含 css 文件的*内容*。 (3认同)