ASP.Net объединяет и объединяет MVC с Cloudfront
В настоящее время я использую 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 ответа
Я не знаком с 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?
Я столкнулся с тем же номером несколько месяцев назад и просто наткнулся на этот пост. Я смог обойти его, создав собственный фильтр 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>