Question

In my MVC5.1 project I'm using bundling and minification with CSS rewriting transformation:

styleBundle.Include("~/Content/Site.css", new CssRewriteUrlTransform());
bundles.Add(styleBundle);

CssRewriteUrlTransform converts image paths relative to the root of the site. But, when I images embedded into css:

span.file {
  background-image: url(data:image/png;base64,iVBORw0KGg+...2AAAAElFTkSuQmCC);
}

this is getting translated into

span.file {
  background-image: url(http://localhost:52253/Content/data:image/png;base64,iVBORg...mCC);
}

And obviously ~/Content/data:image/png;base64... does not exist.

Any way to stop this happening, other than update CSS files to not include embedded images? Or separate into different CSS files, where with actual URL are used and URL-transform this files. And another css with only embedded images.

Était-ce utile?

La solution

Scrap that question. This is a known bug. Currently work around is to separate your css into embedded images and images via url.

Vote for these work-items: https://aspnetoptimization.codeplex.com/workitem/88 and https://aspnetoptimization.codeplex.com/workitem/108

Autres conseils

Checkout my workaround which I've 'bundled' nicely into a NuGet package. https://github.com/benmccallum/AspNetBundling

Otherwise just upgrade to grunt/gulp ;)

If you don't want to extract the embedded images to actual files and you can't wait for a new version of the Microsoft.AspNet.Web.Optimization nuget, you can use the following class.

It's a verbatim copy of CssRewriteUrlTransform except it ignores (crudely ;)) URL's with the data URI syntax.

Gist: https://gist.github.com/janv8000/fa69b2ab6886f635e3df

/// <remarks>Part of Microsoft.AspNet.Web.Optimization.1.1.3, forked to ignore data-uri</remarks>
public class CssRewriteUrlTransformIgnoringDataUri : IItemTransform
{
    internal static string RebaseUrlToAbsolute(string baseUrl, string url)
    {
        if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase))
            return url;
        if (!baseUrl.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            baseUrl = baseUrl + "/";
        return VirtualPathUtility.ToAbsolute(baseUrl + url);
    }

    internal static string ConvertUrlsToAbsolute(string baseUrl, string content)
    {
        if (string.IsNullOrWhiteSpace(content))
        { return content; }

        return new Regex("url\\(['\"]?(?<url>[^)]+?)['\"]?\\)").Replace(content, match =>
        {
            var format = match.Groups["url"].Value;
            if (format.StartsWith("data:image", StringComparison.CurrentCultureIgnoreCase))
            {
                return format;
            }

            return "url(" + RebaseUrlToAbsolute(baseUrl, format) + ")";
        });
    }

    public string Process(string includedVirtualPath, string input)
    {
        if (includedVirtualPath == null)
        {
            throw new ArgumentNullException("includedVirtualPath");
        }
        return ConvertUrlsToAbsolute(VirtualPathUtility.GetDirectory(includedVirtualPath.Substring(1)), input);
    }
}

We were facing the same issue for asp.net mvc with angular project. Issue was for ag-grid base 64 image which was not showing in prod environment.

As a workaround we have removed CssRewriteUrlTransform() & changed the virtual path to match with actual physical path.

Old code
bundles.Add(new StyleBundle("~/bundles/styles").Include("~/Content/Site.css", new CssRewriteUrlTransform());

New code change
bundles.Add(new StyleBundle("~/dist/styles").Include("~/Content/Site.css");

Initially base64 image was looking for bundles folder which was not existing.

Old
background: transparent url(data:image/svg+xml;base64,PHN2ZyB3a...)

was translated to

background: transparent url(/dist/data:image/svg+xml;base64,PHN2ZyB3a...)

After making the mentioned changes base 64 image was not appended with any path.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top