asp.net-mvc 如何在 Razor 视图中内嵌 CSS 样式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14298604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:32:13  来源:igfitidea点击:

How to include CSS styles inline in Razor view?

asp.net-mvcrazorasp.net-mvc-4postal

提问by luksan

I am using Postalto render MVC Razor views and send them via email. I have a custom CSS that I have defined specifically for the email views. Currently I am including them as follows:

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

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

However, this only includes the relative link to the stylesheet, which will not work in an email:

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

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

I want to include the stylesheet inline so that it functions properly in the email. What is the best way to render the contents of a file-based resource within an MVC view?

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

采纳答案by Stay Foolish

I guess you will need to have a custom helper for that. On top of my head, there is no such a method to render the css path including the absolute path of the website.

我想您需要为此拥有一个自定义助手。在我的头顶上,没有这样的方法来呈现包括网站绝对路径在内的 css 路径。

e.g. http:www.example.com/css/EmailStyles.css

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

回答by Paul d'Aoust

I had the same question myself, and came across Premailer.Net. It looks like the library you need. Here's what you'd have to do:

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

  1. Create an extension method to help you embed your CSS into your page; there's an answer on a question on how to embed HTML in a Razor viewthat should help you. I've modified it for embedding 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. Then in your Razor template, just go:

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

    to embed your CSS text.

  3. Install the Premailer.Net package in your project; you can get it through NuGet.

  4. Render your Razor view into a string (I guess that's what Postal is for in your process? I believe RazorEnginecan also do that).

  5. Run the string through Premailer.Net:

    PreMailer pm = new PreMailer();
    string premailedOutput = pm.MoveCssInline(htmlSource, false);
    
  6. Send as an e-mail!

  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;
            }
        }
    }
    
  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. 作为电子邮件发送!

I've been using this technique in production for a while now, and it seems to be working quite well.

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

Edit: Remember that styles on pseudo-elements can't be inlinedbecause they don't exist in the markup. I've also noticed the odd little bug in Premailer.Net -- I think their specificity and cascade rules aren't perfectly conformant. Still, it's pretty good and it's one more piece of code I didn't have to write!

编辑:请记住,伪元素上的样式不能内联,因为它们不存在于标记中。我还注意到 Premailer.Net 中的一个奇怪的小错误——我认为它们的特异性和级联规则并不完全符合。尽管如此,它还是相当不错的,而且它是我不必编写的另一段代码!

回答by dprothero

Upvoted Paul d'Aoust's answer, but I found this version of his helper method to work a little better for me (wouldn't try to encode things like quotes in the CSS):

赞成 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;
    }
  }
}