Asp.net mvc 使ASP.NET绑定为CSS绑定指定媒体=屏幕

Asp.net mvc 使ASP.NET绑定为CSS绑定指定媒体=屏幕,asp.net-mvc,asp.net-mvc-4,bundling-and-minification,asp.net-optimization,Asp.net Mvc,Asp.net Mvc 4,Bundling And Minification,Asp.net Optimization,我只是在尝试ASP.NET4.5捆绑和缩小,但遇到了一个问题 我有大约10个css文件,其中2个最初是在布局中使用属性media=“screen”引用的 由于将css添加到捆绑包的语法不允许您指定应添加此类属性(有意义,因为该属性将应用于整个捆绑包),因此我希望看到@Styles.Render的重载,这将允许我指定html属性,就像在其他html帮助器中一样,但没有 有一个丑陋的解决方案,因为我知道创建的捆绑包的url,所以我可以自己制作标签,但是我会失去ASP.NET处理的缓存机制,因为它允许

我只是在尝试ASP.NET4.5捆绑和缩小,但遇到了一个问题

我有大约10个css文件,其中2个最初是在布局中使用属性media=“screen”引用的

由于将css添加到捆绑包的语法不允许您指定应添加此类属性(有意义,因为该属性将应用于整个捆绑包),因此我希望看到@Styles.Render的重载,这将允许我指定html属性,就像在其他html帮助器中一样,但没有

有一个丑陋的解决方案,因为我知道创建的捆绑包的url,所以我可以自己制作标签,但是我会失去ASP.NET处理的缓存机制,因为它允许ASP.NET呈现标签本身


有没有办法做到这一点,我是否错过了什么?或者这仅仅是设计团队的疏忽?

不幸的是,目前没有一种很好的方法来钩住标签的呈现方式,我们考虑添加一个钩子,以便您可以添加自己的方法来呈现每个脚本/样式标签。听起来我们确实需要这样做。添加起来应该很简单,我将创建一个工作项来启用此场景


作为一种临时解决方法,如果您愿意丢失Styles.Render提供的调试/发布功能,您可以使用Styles.Url来呈现对捆绑包的引用,而Styles.Url只提供捆绑包Url,您可以将其嵌入到您自己的标记中。

好吧,这是一个丑陋的黑客行为,但希望该团队能在下一个版本中添加一个内置的方法来实现这一点

我就是这样解决的,维护缓存字符串,并且仍然能够将媒体属性添加到标记中

@{
    var cssMediaBundleUrl = BundleTable.Bundles.ResolveBundleUrl("~/stylesheets/mediacss", true);
}
<link href="@cssMediaBundleUrl" rel="stylesheet" type="text/css" media="screen" />
@{
var cssmedibundleurl=BundleTable.Bundles.ResolveBundleUrl(“~/stylesheets/mediacss”,true);
}

我想我可以将其转换为Html帮助程序,稍后再进行编辑。

在不影响调试能力的情况下,解决此问题的另一个选项是:

public static IHtmlString Render(string path, IDictionary<string, object> htmlAttributes)
{
    var attributes = BuildHtmlStringFrom(htmlAttributes);

#if DEBUG
    var originalHtml = Styles.Render(path).ToHtmlString();
    string tagsWithAttributes = originalHtml.Replace("/>", attributes + "/>");
    return MvcHtmlString.Create(tagsWithAttributes);
#endif

    string tagWithAttribute = string.Format(
        "<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\"{1} />", 
        Styles.Url(path), attributes);

    return MvcHtmlString.Create(tagWithAttribute);
}
代码的其余部分:

public static IHtmlString Render(string path, object htmlAttributes)
{
    return Render(path, new RouteValueDictionary(htmlAttributes));
}

private static string BuildHtmlStringFrom(IEnumerable<KeyValuePair<string, object>> htmlAttributes)
{
    var builder = new StringBuilder();

    foreach (var attribute in htmlAttributes)
    {
        builder.AppendFormat(" {0}=\"{1}\"", attribute.Key, attribute.Value);
    }

    return builder.ToString();
}
公共静态IHtmlString呈现(字符串路径、对象htmlAttributes)
{
返回渲染(路径,新RouteValueDictionary(htmlAttributes));
}
私有静态字符串BuildHtmlStringFrom(IEnumerable htmlAttributes)
{
var builder=新的StringBuilder();
foreach(htmlAttributes中的var属性)
{
AppendFormat(“{0}=\”{1}\”,attribute.Key,attribute.Value);
}
返回builder.ToString();
}

我写了一篇关于这个主题的博文:

我找到了一个更优雅的解决方案

我使用的是
样式.RenderFormat(format,bundle)

我有一个
BundlesFormats
类,它有一个名为
PRINT
的属性,我这样使用它:

public class BundlesFormats
{
    public const string PRINT = @"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />";
}

为什么不直接使用@media print?检查一下这么复杂,为什么不使用:

bundles.Add<StylesheetBundle>("~/Css/site.css", b => b.Media = "screen");
bundles.Add(“~/Css/site.Css”,b=>b.Media=“screen”); ?

Web表单解决方案 在BundleConfig.cs中:

//Print css must be a separate bundle since we are going to render it with a media=print
Bundles.Add(new StyleBundle("~/bundles/printCSS").Include("~/Content/Print.css"));
<asp:Literal runat="server" ID="litCssPrint" />
litCssPrint.Text = Styles.RenderFormat(@"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />", "~/bundles/printCSS").ToHtmlString();
母版页:

//Print css must be a separate bundle since we are going to render it with a media=print
Bundles.Add(new StyleBundle("~/bundles/printCSS").Include("~/Content/Print.css"));
<asp:Literal runat="server" ID="litCssPrint" />
litCssPrint.Text = Styles.RenderFormat(@"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />", "~/bundles/printCSS").ToHtmlString();

母版页代码文件:

//Print css must be a separate bundle since we are going to render it with a media=print
Bundles.Add(new StyleBundle("~/bundles/printCSS").Include("~/Content/Print.css"));
<asp:Literal runat="server" ID="litCssPrint" />
litCssPrint.Text = Styles.RenderFormat(@"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />", "~/bundles/printCSS").ToHtmlString();
litCssPrint.Text=style.RenderFormat(@“”“~/bundles/printCSS”).ToHtmlString();
我进一步采纳了他的建议

我可能编码过度了,但是为了可读性,我创建了一个静态类来模拟
样式.Render
格式

public static class StyleExtensions
{
    public enum Format
    {
        Async,
        Preload,
    }

    public static IHtmlString Render(string contentPath, Format format)
    {
        switch (format)
        {
            case Format.Async:
            return contentPath.ToAsyncFormat();
            case Format.Preload:
            return contentPath.ToPreloadFormat();
            default:
            return new HtmlString(string.Empty);
        }
    }

    public static IHtmlString RenderAsync(string contentPath)
    {
        return contentPath.ToAsyncFormat();
    }

    public static IHtmlString RenderPreload(string contentPath)
    {
        return contentPath.ToPreloadFormat();
    }

    public static IHtmlString ToAsyncFormat(this string contentPath)
    {
        return Styles.RenderFormat("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" media=\"print\" onload=\"this.media='all';this.onload=null;\">", contentPath);
    }

    public static IHtmlString ToPreloadFormat(this string contentPath)
    {
        return Styles.RenderFormat("<link rel=\"preload\" href=\"{0}\" as=\"style\" onload=\"this.rel='stylesheet';this.onload=null;\">", contentPath);
    }
}


郝,我猜你是ASP.NET团队的成员?奇怪的是,其他Html帮助程序确实有重载,允许开发人员设置Html属性,而捆绑渲染器方法没有。我正在考虑对生成的标记(包括缓存字符串)进行黑客攻击,然后自己添加媒体属性,这样我仍然可以拥有缓存,并且可以添加它。我只是觉得这真的很奇怪,团队没有这么做。找到了一种通过框架实现的方法,尽管这并不好。我将在bitYes中发布它,Hao是MSFT优化框架的首席开发人员。您可以这样做:@GR7在升级到VS 2013 Express for Web后,这开始产生404错误。我在《如何修复?》一书中发表了这篇文章。安德鲁斯,你有没有尝试过其他人发表的任何替代方案?我还没有重温过这段代码,但肯定会很快重温,希望如此。不,我没有。请确认您的/Hao解决方案在VS2013中不起作用,然后我开始研究其他方法。在这种情况下,这应该不标记为answerJust use@Styles.RenderFormat(查看我的答案了解更多详细信息)只是一个说明:此解决方案目前需要“Microsoft ASP.NET Web Optimization Framework”的预发布版本。稳定版本没有“RenderFormat”方法。这是1.1.0版本的一部分。我花了一分钟才意识到它可以在一行上完成:@Styles.RenderFormat(“,“~/bundles/Content/print”),我认为这是最优雅的解决方案,IMO。除非他提到的阻塞问题得到解决,这是一个相关的点,我喜欢这种方法,因为我可以在我的主样式包中包含只打印的文件。这里使用的包版本是什么
Microsoft.AspNet.Web.Optimization.1.1.3
不包含通用添加方法这些东西从何而来
Add()
StylesheetBundle