我只是尝试ASP.NET 4.5捆绑和缩小,并遇到了一个问题。
我有大约10个css文件,其中2个最初使用属性media =“screen”在布局中引用。
由于将css添加到bundle的语法不允许你指定应该添加这样的属性(有意义,因为该属性将适用于整个bundle),我希望看到@Styles的重载。渲染允许我指定html属性,就像在其他Html助手中一样,但没有。
有一个丑陋的解决方案,因为我知道创建的bundle的url,我可以自己制作标签,但是我会失去ASP.NET处理的缓存机制,允许它渲染标记本身。
有没有办法做到这一点,我错过了什么吗?或者这仅仅是对设计团队的监督?
答案 0 :(得分:74)
我找到了一个更优雅的解决方案。
我正在使用Styles.RenderFormat(format, bundle)
。
我有一个BundlesFormats
类,其中包含一个名为PRINT
的属性,我这样使用它:
public class BundlesFormats
{
public const string PRINT = @"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />";
}
在cshtml中:
@Styles.RenderFormat(BundlesFormats.PRINT, "~/bundles/Content/print")
答案 1 :(得分:13)
嗯,这是一个丑陋的黑客,但希望团队会在下一个版本中添加一个内置的方法来实现它。
这是我解决它的方法,维护缓存字符串并仍然能够将媒体属性添加到标记。
@{
var cssMediaBundleUrl = BundleTable.Bundles.ResolveBundleUrl("~/stylesheets/mediacss", true);
}
<link href="@cssMediaBundleUrl" rel="stylesheet" type="text/css" media="screen" />
猜猜我可以把它变成一个Html帮助器,稍后会这样做并编辑。
答案 2 :(得分:6)
在不影响调试能力的情况下解决此问题的另一个选择可能是:
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);
}
我正在做的只是将给定的html属性附加到标记的末尾(在调试模式下)或附加到唯一链接标记的末尾(当启用缩小/捆绑时)。
视图中的用法:
@Bundles.Render("~/css/print", new { media = "print" })
其余代码:
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();
}
我写了一篇关于这个主题的博文:http://danielcorreia.net/blog/quick-start-to-mvc4-bundling/
答案 3 :(得分:3)
不幸的是,没有一种很好的方式来挂钩当前如何呈现标记,我们考虑添加一个钩子,以便您可以添加自己的方法来呈现每个脚本/样式标记。听起来我们确实需要这样做。添加起来应该非常简单,我将创建一个工作项来启用此方案......
作为一种临时解决方法,如果您愿意丢失Styles.Render为您提供的调试/发布功能,您可以使用Styles.Url呈现对该包的引用,这样可以为您提供捆绑网址,您可以嵌入在你自己的标签内。
答案 4 :(得分:2)
为什么不直接使用@media打印?查看http://www.phpied.com/5-years-later-print-css-still-sucks/
答案 5 :(得分:0)
在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();
答案 6 :(得分:0)
我进一步采纳了Adam Tal的建议。
我可能对其进行了过度编码,但是出于可读性考虑,我创建了一个静态类来模仿Styles.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);
}
}
我可能会擦除直接构造函数或枚举构造函数,并且您实际上也可以将字符串扩展名也放入方法中,这取决于对您更有意义的方法,但是您可以相应地使用以下两种方法之一进行调用:
@StyleExtensions.Render("~/Content/bundle-bootstrap", StyleExtensions.Format.Preload)
@StyleExtensions.Render("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;700&display=swap", StyleExtensions.Format.Preload)
@StyleExtensions.Render(Url.Content("~/Content/Styles/Primary.min.css"), StyleExtensions.Format.Async)
或
@StyleExtensions.RenderPreload("~/Content/bundle-bootstrap")
@StyleExtensions.RenderPreload("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;700&display=swap")
@StyleExtensions.RenderAsync(Url.Content("~/Content/Styles/Primary.min.css"))
答案 7 :(得分:-1)
如此复杂,为什么不使用:
bundles.Add<StylesheetBundle>("~/Css/site.css", b => b.Media = "screen");