44 votes

Faire en sorte que le bundling ASP.NET spécifie media=screen pour le bundle CSS

Je suis en train d'essayer le regroupement et la minification ASP.NET 4.5, et j'ai rencontré un problème.

J'ai environ 10 fichiers css, dont 2 ont été référencés à l'origine dans la mise en page en utilisant l'attribut media="screen".

Puisque la syntaxe pour ajouter une css au bundle ne permet pas de spécifier qu'un tel attribut doit être ajouté (ce qui est logique, puisque l'attribut s'appliquerait à tout le bundle), j'espérais voir une surcharge de @Styles.Render qui me permettrait de spécifier des attributs html, comme dans d'autres aides Html, mais il n'y en a pas.

Il existe une solution peu glorieuse, dans laquelle, puisque je connais l'url du bundle créé, je pourrais créer la balise moi-même, mais je perdrais le mécanisme de mise en cache qui est géré par ASP.NET en lui permettant de rendre la balise elle-même.

Existe-t-il un moyen de faire cela, ai-je raté quelque chose ? Ou s'agit-il simplement d'un oubli de l'équipe de conception ?

0 votes

Il suffit d'utiliser @Styles.RenderFormat (voir ma réponse pour des informations plus détaillées).

77voto

Adam Tal Points 2094

J'ai trouvé une solution plus élégante.

J'utilise le Styles.RenderFormat(format, bundle) .

J'ai un BundlesFormats avec une propriété appelée PRINT et je l'utilise comme suit :

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

Et dans le cshtml :

@Styles.RenderFormat(BundlesFormats.PRINT, "~/bundles/Content/print")

5 votes

Juste une note : Cette solution nécessite actuellement la version prerelease de "Microsoft ASP.NET Web Optimization Framework". La version stable ne dispose pas de la méthode "RenderFormat".

3 votes

Cela fait maintenant partie de la version 1.1.0.

5 votes

Il m'a fallu une minute pour réaliser que cela pouvait se faire sur une seule ligne : @Styles.RenderFormat("<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />", "~/bundles/Content/print")

14voto

GR7 Points 1330

Il s'agit d'un piratage peu esthétique, mais il est à espérer que l'équipe ajoutera un moyen intégré de le faire dans la prochaine version.

Voici comment j'ai résolu le problème, en conservant la chaîne de mise en cache et en étant toujours en mesure d'ajouter l'attribut media à la balise.

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

Je suppose que je peux transformer ceci en une aide Html, je le ferai plus tard et j'éditerai.

29 votes

Vous pouvez simplement faire ceci : < link href="@Styles.Url("~/stylehseets/mediacss")" rel="stylesheet" type="text/css" media="screen" />

0 votes

@GR7 Après la mise à jour vers VS 2013 Express For Web, cela commence à produire des erreurs 404. Je l'ai posté dans stackoverflow.com/questions/20052278/ Comment réparer ?

0 votes

@Andrus, avez-vous essayé l'une des alternatives proposées par d'autres personnes ? Je n'ai pas encore revisité ce code, mais je le ferai certainement bientôt, si tout va bien.

6voto

Daniel Correia Points 96

Une autre option pour résoudre ce problème, sans compromettre la capacité de débogage, pourrait être :

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);
}

Ce que je fais, c'est ajouter les attributs html donnés à la fin des balises (en mode débogage) ou à la fin de la seule balise de lien (lorsque la minification/le regroupement sont activés).

L'utilisation dans les vues :

@Bundles.Render("~/css/print", new { media = "print" })

Le reste du 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();
}

J'ai écrit un article de blog sur ce sujet : http://danielcorreia.net/blog/quick-start-to-mvc4-bundling/

3voto

Hao Kung Points 13035

Malheureusement, il n'y a pas de bonne façon de s'accrocher à la façon dont les balises sont rendues actuellement, nous avons pensé à ajouter un crochet pour que vous puissiez ajouter votre propre méthode pour rendre chaque balise script/style. Il semble que nous ayons besoin de le faire. Cela devrait être assez simple à ajouter, je vais créer un élément de travail pour permettre ce scénario...

Comme solution temporaire, si vous êtes prêt à perdre la fonctionnalité de débogage/libération que Styles.Render vous donne, vous pouvez rendre une référence au bundle en utilisant Styles.Url qui vous donnera juste l'url du bundle, vous pouvez l'incorporer à l'intérieur de votre propre balise.

0 votes

Hao, je suppose que tu fais partie de l'équipe ASP.NET ? Il est étrange que les autres Html Helpers disposent de surcharges permettant au développeur de définir des attributs html, alors que les méthodes de rendu de Bundle n'en ont pas. Je pense pirater la balise générée (qui inclurait la chaîne de mise en cache) et ajouter l'attribut media moi-même, de cette façon j'aurais toujours la mise en cache et je pourrais l'ajouter Je pense juste que c'est vraiment bizarre que cela ait échappé à l'équipe.

0 votes

J'ai trouvé un moyen de le faire à travers le cadre, bien que ce ne soit pas agréable. Je le posterai dans un instant

0 votes

Oui, Hao est le principal développeur de MSFT pour le cadre d'optimisation.

2voto

WizxX20 Points 51

Pourquoi ne pas utiliser @media print ? Consultez http://www.phpied.com/5-years-later-print-css-still-sucks/

1 votes

À moins que le problème de blocage auquel il fait référence n'ait été résolu, il s'agit d'un point pertinent

1 votes

J'aime cette méthode parce que je peux inclure le fichier à imprimer uniquement dans mon paquet de styles principal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X