2012-09-02 16 views
40

Me pregunto qué es lo que no hago aquí. Estoy usando ASP.NET C# MVC4 y quiero utilizar la nueva función de optimización css/js.MVC4 - El agrupamiento no funciona cuando las optimizaciones están establecidas en verdadero

Aquí es mi parte HTML

@Styles.Render("~/content/css") 

Aquí es mi BunduleConfig.cs parte

bundles.Add(new StyleBundle("~/content/css").Include(
         "~/content/css/reset.css", 
         "~/content/css/bla.css")); 

// BundleTable.EnableOptimizations = true; 

salida (obras):

<link href="/content/css/reset.css" rel="stylesheet"/> 
<link href="/content/css/bla.css" rel="stylesheet"/> 

Sin embargo cuando Descomentar BundleTable.EnableOptimizations = true; salida HTML se parece a esto

<link href="/content/css?v=5LoJebKvQJIN-fKjKYCg_ccvmBC_LF91jBasIpwtUcY1" rel="stylesheet"/> 

Y esto es, por supuesto, es 404. No tengo idea de dónde hice algo mal, por favor ayuda, la primera vez que trabajo con MVC4.

+0

¿Qué ocurre si crea los archivos ~ content/css/reset.min.css y bla.min.css que EnableOptimizations = true tiende a buscar? – Phil

+0

@Phil todavía 404. – sed

+0

Acabo de crear un proyecto vacío y lo intenté con dos archivos 'css' y sucedió lo mismo. Tal vez es porque puse mis archivos css en la carpeta '/ content/css /' y no solo '/ content /' sin embargo lo dudo ... – sed

Respuesta

64

Imagino que el problema es que pone el paquete en una URL virtual que realmente existe, pero es un directorio.

MVC está creando un archivo virtual de su paquete y lo está sirviendo desde la ruta que especifique como la ruta del paquete.

La solución correcta para ese problema es utilizar una ruta de paquete que no se correlacione directamente con un directorio existente y en su lugar utiliza un nombre de archivo virtual (que no se correlaciona con un nombre de archivo real) dentro de ese directorio.

Ejemplo:

si su sitio tiene una carpeta llamada/content/css, css que su paquete de la siguiente manera:

En BundleConfig.cs:

bundles.Add(new StyleBundle("~/content/css/AllMyCss.css").Include(
         "~/content/css/reset.css", 
         "~/content/css/bla.css")); 

Y en la página:

@Styles.Render("~/content/css/AllMyCss.css") 

tenga en cuenta que este se supone que no tiene un archivo llamado AllMyCss.css en su css f mayor.

+0

Sí, este es el problema, gracias. – sed

+6

¿No colocar el paquete en un directorio no existente causa problemas con las referencias relativas en el CSS? http://devwhib.blogspot.com/2012/08/mvc-4-bundles-where-are-my-css.html – gidmanma

+0

+1 Gracias. Acabo de resolver mi problema también. – ryanulit

3

Eso me parece correcto. Cuando las optimizaciones están habilitadas, solo tendrá una única referencia y será para el nombre que especificó en su StyleBundle (/ content/css). En el modo de depuración (o más específicamente con debug = false en su configuración web) obtendrá los archivos no optimizados de forma normal. Si miras, verás que son solo texto mientras los escribiste. Sin embargo, cuando las optimizaciones están activadas (generalmente cuando se ejecuta en modo de lanzamiento) obtendrá una URL que parece extraña.

Si mira el resultado de eso, se verá minimizado. La cadena de consulta? V = 5KLoJ .... se basa en un hash tomado de los archivos en el paquete. Esto es para que la referencia se pueda almacenar en caché HTTP de forma segura durante el tiempo que desee. Por siempre si te apetece, pero creo que el valor predeterminado es de un año. Sin embargo, si modifica cualquiera de sus hojas de estilo, generará un nuevo hash y eso es "eliminación de memoria caché", por lo que obtendrá una nueva copia en el navegador.

Habiendo dicho todo eso, no estoy seguro de por qué está obteniendo un 404. Sospecho que tiene algo que ver con su configuración de enrutamiento o su configuración de IIS. ¿Estás ejecutando Visual Studio con IISExpress?

+0

Estoy ejecutando VS2010 usando el servidor de desarrollo ASP.NET (integrado para pruebas/depuración). – sed

+0

¿Está llamando a EnableDefaultBundles()? De lo contrario, parece que sus URL no se pasan: intente cambiar el modo de su grupo de aplicaciones a "integrado". – cirrus

26

No estoy seguro si es la optimización web, o WebGrease que es tan delicado pero uno (o ambos) de ellos es y debe ser extremadamente cuidadoso.

En primer lugar no hay nada malo con su código:

bundles.Add(new StyleBundle("~/content/css").Include(
         "~/content/css/reset.css", 
         "~/content/css/bla.css")); 

De hecho, esto es exactamente lo que hace Microsoft. La razón principal por la que no usa usa ~/bundles para css es que las rutas relativas se estropean para las imágenes. Piense en cómo ve su navegador un paquete, exactamente de la misma forma en que ve cualquier otra URL, y todas las reglas relacionadas con la ruta normal aún se aplican con respecto a las rutas relativas. Imagina que tu CSS tiene una ruta de imagen al ../images/bullet.png. Si estuviera usando ~/bundles, el navegador estaría buscando en un directorio sobre bundles que en realidad no existe. Probablemente terminará buscando en ~/images donde probablemente lo tengas en ~/content/images.

he encontrado un par de cosas que realmente pueden romper y provocar errores 404:

  • FYI: Mi estructura de directorios es Content/CSS que contiene una carpeta para las imágenes images CSS.
  • que tienen EnableOptimizations=true para forzar el uso de haces mientras que las pruebas
  • Lo primero que debe hacer es 'Ver código fuente' y haga clic en los enlaces de CSS para ver si funcionan

Digamos que estamos desarrollando un sitio sobre gatos Es posible que tenga este

@Styles.Render("~/Content/css/cats.css") // dont do this - see below why 

bundles.Add(new StyleBundle("~/content/css/cats.css").Include(
        "~/content/css/reset.css", 
        "~/content/css/bla.css")); 

Esto genera un vínculo CSS para esta ruta en el código HTML:

/Content/css/cats.css?v=JMoJspikowDah2auGQBfQAWj1OShXxqAlXxhv_ZFVfQ1 

Sin embargo, esto dará un 404 porque puse una extensión .css e IIS (creo) obtiene confuso.

Si lo cambio a esto, entonces funciona bien:

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

bundles.Add(new StyleBundle("~/content/css/cats").Include(
        "~/content/css/reset.css", 
        "~/content/css/bla.css")); 

Otro problema ya se ha comentado en otras es que no se debe hacer

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

si tiene un directorio css o archivo (es poco probable que tenga un archivo llamado css sin extensión) en su directorio Content.

Un truco adicional es que usted necesita para asegurarse de que el código HTML generado tiene un número de versión

<link href="/Content/css/cats?v=6GDW6wAXIN5DJCxVtIkkxLGpojoP-tBQiKgBTQMSlWw1" rel="stylesheet"/> 

Si no lo hace y se parece a esto, entonces es probable que no tienen una coincidencia exacta para el nombre del paquete entre su tabla de paquete y en su archivo cshtml.

<link href="/Content/css/cats" rel="stylesheet"/> 
+0

I No estoy seguro si estoy leyendo mal aquí, pero parece que estás sugiriendo que 'nuevo StyleBundle ("~/content/css") 'está bien y es recomendado, pero también que no está bien si tienes' css' carpeta en su directorio 'content' (que es una configuración bastante estándar). –

+1

Esa es la respuesta correcta –

+0

@MattMitchell en realidad eso fue lo que dijo OP, así que estaba explicando por qué causaba el error y por qué no debería 't have it named como such. –

3

Acabo de resolver un problema similar. El problema fue el siguiente, instalé 'elegido' a través de NuGet. Y en la clase BundleConfig, la línea que incluye el archivo CSS era la siguiente:

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",)); 
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/chosen.css")); 

Algunos donde en esa clase que tenía esta línea:

BundleTable.EnableOptimizations = true; 

La solución era combinar la 2 bundles.Add() como tal:

bundles.Add(new StyleBundle("~/Content/css").Include(
          "~/Content/site.css", 
          "~/Content/chosen.css" 
         )); 

Y eso lo arregló para mí.

+0

'BundleTable.EnableOptimizations = true;' hizo el truco! – rotgers

4

No olvide asegurarse de que la agrupación HttpModule está allí.

<modules> 
    <remove name="BundleModule" /> 
    <add name="BundleModule" type="System.Web.Optimization.BundleModule" /> 
</modules> 

Esto me picó la primera vez. No estoy seguro de si el paquete NuGet debe agregar la configuración necesaria, pero no fue en mi caso.

0

También podría ser porque no ha implementado bundleconfig.json en el servidor por algún motivo.

Cuestiones relacionadas