可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm just trying out ASP.NET 4.5 bundling and minification, and ran into an issue.
I've got around 10 css files, of which 2 were originally referenced in the layout using the attribute media="screen".
Since the syntax for adding a css to the bundle does not let you specify that such attribute should be added (makes sense, since the attribute would apply for the whole bundle), I was hoping to see an overload of @Styles.Render that would allow me to specify html attributes, like in other Html helpers, but there is none.
There is an ugly solution, in which since I know the url of the bundle created, i could just craft the tag myself, but I'd lose the caching mechanism that is handled by ASP.NET by allowing it to render the tag itself.
Is there a way to do this, am I missing something? Or is this just an oversight of the design team?
回答1:
I've found a more elegant solution.
I'm using the Styles.RenderFormat(format, bundle)
.
I have a BundlesFormats
class with a property called PRINT
and I use it like so:
public class BundlesFormats
{
public const string PRINT = @"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />";
}
And in the cshtml:
@Styles.RenderFormat(BundlesFormats.PRINT, "~/bundles/Content/print")
回答2:
Well, it's an ugly hack, but hopefully the team will add a built-in way to do it in the next release.
This is how I solved it, maintaining the caching string and still being able to add the media attribute to the tag.
@{
var cssMediaBundleUrl = BundleTable.Bundles.ResolveBundleUrl("~/stylesheets/mediacss", true);
}
<link href="@cssMediaBundleUrl" rel="stylesheet" type="text/css" media="screen" />
Guess I can turn this into an Html helper, will do that later and edit.
回答3:
Another option to solve this issue, without compromising the debug ability, could be:
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);
}
What I'm doing is just appending the given html attributes to the end of the tags (on debug mode) or to the end of the only link tag (when minification/bundling are enabled).
The usage in views:
@Bundles.Render("~/css/print", new { media = "print" })
The rest of the code:
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();
}
I've wrote a blog post about this subject: http://danielcorreia.net/blog/quick-start-to-mvc4-bundling/
回答4:
Unfortunately there isn't a great way to hook into how the tags are rendered currently, we thought about adding a hook so you could add your own method to render each script/style tag. It sounds like we do need to do that. Should be pretty simple to add, I'll create a work item to enable this scenario...
As a temporary workaround, if you are willing to lose the debug/release functionality that Styles.Render gives you, you can render a reference to the bundle using Styles.Url which would give you just the bundle url, you can embed that inside your own tag.
回答5:
Why not just use @media print? Check out http://www.phpied.com/5-years-later-print-css-still-sucks/
回答6:
Web Forms Solution
In 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"));
Master Page:
<asp:Literal runat="server" ID="litCssPrint" />
Master Page Code File:
litCssPrint.Text = Styles.RenderFormat(@"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />", "~/bundles/printCSS").ToHtmlString();
回答7:
So complicated, why not to use:
bundles.Add<StylesheetBundle>("~/Css/site.css", b => b.Media = "screen");
?