ASP.Net объединяет и объединяет MVC с Cloudfront - PullRequest
4 голосов
/ 15 января 2012

В настоящее время я использую Amazon Cloudfront для обслуживания статических объектов на моем сайте ASP.Net MVC3 C #. Таким образом, все статические ресурсы имеют добавление http://cdn.domainname.com/ перед ресурсом.

В то же время я использую combres и combred mvc для сжатия и объединения моих CSS и Javascript.

Тег для вывода минимизированных объединенных файлов выглядит следующим образом.

@Html.Raw(WebExtensions.CombresLink("siteCss"))
@Html.Raw(WebExtensions.CombresLink("siteJs"))

При этом на моем сайте появляются ссылки на

<link rel="stylesheet" type="text/css" href="/combres.axd/siteCss/-63135510/"/>
<script type="text/javascript" src="/combres.axd/siteJs/-561397631/"></script> 

Как вы видите, мой облачный фронт не находится перед ним, поэтому я не получаю преимущества облачного фронта с этими файлами.

Есть ли кто-нибудь, кто знает, как вставить мой CDN, не изменяя исходный код DLL-файла Actall Combress?

Ответы [ 2 ]

4 голосов
/ 08 февраля 2012

Я не знаком с Cloudfront, но с Combres (последний выпуск) вы можете изменить имя хоста (которое добавляется в качестве префикса перед /combres.axd ..., установив атрибут host в. Например:

 <resourceSets url="~/combres.axd"
                host="static.mysite.com"
                defaultDuration="365"
                defaultVersion="auto"
                defaultDebugEnabled="false"
                defaultIgnorePipelineWhenDebug="true"
                localChangeMonitorInterval="30"
                remoteChangeMonitorInterval="60"
                > 

Пожалуйста, дайте мне знать, если этот подход работает с CloudFront?

1 голос
/ 18 апреля 2012

Я столкнулся с той же проблемой несколько месяцев назад и только что наткнулся на этот пост.Я смог обойти его, создав собственный фильтр Combres (FixUrlsInCSSFilter), который будет считывать значение «базового URL» из файла web.config или настройки базы данных и применять его ко всем URL-адресам изображений combres.

Надеюсь, это кому-нибудь поможет ...

combres.xml :

<combres xmlns='urn:combres'>
  <filters>
    <filter type="MySite.Filters.FixUrlsInCssFilter, MySite" />
  </filters>

FixUrlsInCssFilter - большая часть этого была скопированаиз исходного отраженного файла

    public sealed class FixUrlsInCssFilter : ISingleContentFilter
{
    /// <inheritdoc cref="IContentFilter.CanApplyTo" />
    public bool CanApplyTo(ResourceType resourceType)
    {
        return resourceType == ResourceType.CSS;
    }

    /// <inheritdoc cref="ISingleContentFilter.TransformContent" />
    public string TransformContent(ResourceSet resourceSet, Resource resource, string content)
    {
        string baseUrl = AppSettings.GetImageBaseUrl();

        return Regex.Replace(content, @"url\((?<url>.*?)\)", match => FixUrl(resource, match, baseUrl),
            RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
    }

    private static string FixUrl(Resource resource, Match match, string baseUrl)
    {
        try
        {
            const string template = "url(\"{0}\")";
            var url = match.Groups["url"].Value.Trim('\"', '\'');

            while (url.StartsWith("../", StringComparison.Ordinal))
            {
                url = url.Substring(3); // skip one '../'
            }

            if (!baseUrl.EndsWith("/"))
                baseUrl += "/";

            if (baseUrl.StartsWith("http"))
            {
                return string.Format(CultureInfo.InvariantCulture, template, baseUrl + url);
            }
            else
                return string.Format(CultureInfo.InvariantCulture, template, (baseUrl + url).ResolveUrl());
        }
        catch (Exception ex)
        {
            // Be lenient here, only log.  After all, this is just an image in the CSS file
            // and it should't be the reason to stop loading that CSS file.
            EventManager.RaiseExceptionEvent("Cannot fix url " + match.Value, ex);
            return match.Value;
        }
    }
}

#region Required to override FixUrlsInCssFilter for Combres

public static class CombresExtensionMethods
{
    /// <summary>
    ///   Returns the relative HTTP path from a partial path starting out with a ~ character or the original URL if it's an absolute or relative URL that doesn't start with ~.
    /// </summary>
    public static string ResolveUrl(this string originalUrl)
    {
        if (string.IsNullOrEmpty(originalUrl) || IsAbsoluteUrl(originalUrl) || !originalUrl.StartsWith("~", StringComparison.Ordinal))
            return originalUrl;

        /* 
         * Fix up path for ~ root app dir directory
         * VirtualPathUtility blows up if there is a 
         * query string, so we have to account for this.
         */
        var queryStringStartIndex = originalUrl.IndexOf('?');
        string result;
        if (queryStringStartIndex != -1)
        {
            var baseUrl = originalUrl.Substring(0, queryStringStartIndex);
            var queryString = originalUrl.Substring(queryStringStartIndex);
            result = string.Concat(VirtualPathUtility.ToAbsolute(baseUrl), queryString);
        }
        else
        {
            result = VirtualPathUtility.ToAbsolute(originalUrl);
        }

        return result.StartsWith("/", StringComparison.Ordinal) ? result : "/" + result;
    }

    private static bool IsAbsoluteUrl(string url)
    {
        int indexOfSlashes = url.IndexOf("://", StringComparison.Ordinal);
        int indexOfQuestionMarks = url.IndexOf("?", StringComparison.Ordinal);

        /*
         * This has :// but still NOT an absolute path:
         * ~/path/to/page.aspx?returnurl=http://www.my.page
         */
        return indexOfSlashes > -1 && (indexOfQuestionMarks < 0 || indexOfQuestionMarks > indexOfSlashes);
    }
}

#endregion

класс AppSettings - для получения значения из web.config.Я также использую это для построения пути для изображений, которые не обрабатываются combres ...

    public class AppSettings
{
    /// <summary>
    /// Retrieves the value for "ImageBaseUrl" if the key exists
    /// </summary>
    /// <returns></returns>
    public static string GetImageBaseUrl()
    {
        string baseUrl = "";

        if (ConfigurationManager.AppSettings["ImageBaseUrl"] != null)
            baseUrl = ConfigurationManager.AppSettings["ImageBaseUrl"];

        return baseUrl;
    }
}

значения web.config

<appSettings>
   <add key="ImageBaseUrl" value="~/Content/Images/" /> <!--For Development-->
   <add key="ImageBaseUrl" value="https://d209523005EXAMPLE.cloudfront.net/Content/Images/" /> <!--For Production-->
</appSettings>
...