Кэширование клиента MVC
По умолчанию пакет MVC кэшируется на клиенте в течение 1 года. Можно ли вручную настроить его для заголовков клиентов (для одного конкретного пакета)?
Мне нужно установить пользовательские заголовки истечения для одного из моих пакетов. Я не могу полагаться на "v = hash" querystring, потому что этот пакет предназначен для внешнего веб-сайта, и они не будут изменять URL-адрес, указывающий на мой пакет, каждый раз, когда я его изменяю.
Я попытался создать собственный класс Bundle (наследовать Bundle) и переопределить метод GenerateBundleResponse(). Таким образом, я могу контролировать кеширование сервера, но единственным способом настройки кэширования клиентов является установка BundleResponse.Cacheability(общедоступный, закрытый, nocache и т.д.). Но я не могу настроить заголовки вручную. У меня есть доступ к BundleContext (и это HttpContext), но когда я устанавливаю заголовки в этом контексте, это будет иметь влияние и на все остальные запросы.
Ответы
Ответ 1
К сожалению, нет способа. Вы можете найти причину во внутренней реализации комплектации. в классе BundleHandler
ProcessRequest вызывает ProcessRequest
, внутренний метод класса Bundle
и вызывает SetHeaders непосредственно перед HttpContext.Response.Write
. Поэтому кеш клиента устанавливается на один год перед записью ответа.
Примечание: BundleHandler
- это внутренний закрытый класс: internal sealed class BundleHandler : IHttpHandler
В классе BundleHandler
:
public void ProcessRequest(HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.Response.Clear();
BundleContext context2 = new BundleContext(new HttpContextWrapper(context), BundleTable.Bundles, this.BundleVirtualPath);
if (!Bundle.GetInstrumentationMode(context2.HttpContext) && !string.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"]))
{
context.Response.StatusCode = 304;
}
else
{
this.RequestBundle.ProcessRequest(context2);
}
}
В классе Bundle
:
internal void ProcessRequest(BundleContext context)
{
context.EnableInstrumentation = GetInstrumentationMode(context.HttpContext);
BundleResponse bundleResponse = this.GetBundleResponse(context);
SetHeaders(bundleResponse, context);
context.HttpContext.Response.Write(bundleResponse.Content);
}
private static void SetHeaders(BundleResponse bundle, BundleContext context)
{
if (bundle.ContentType != null)
{
context.HttpContext.Response.ContentType = bundle.ContentType;
}
if (!context.EnableInstrumentation)
{
HttpCachePolicyBase cache = context.HttpContext.Response.Cache;
cache.SetCacheability(bundle.Cacheability);
cache.SetOmitVaryStar(true);
cache.SetExpires(DateTime.Now.AddYears(1));
cache.SetValidUntilExpires(true);
cache.SetLastModified(DateTime.Now);
cache.VaryByHeaders["User-Agent"] = true;
}
}
Ответ 2
Поведение ASP.NET MVC по умолчанию по умолчанию заключается в том, что если какой-либо из файлов, которые составляют изменение пакета, строка запроса для этого пакета автоматически изменится - если вы используете в своем коде зрения следующее:
@Scripts.Render("bundle name")
Итак, это означает, что если у вас есть новая версия файла, который находится в комплекте, то в следующий раз, когда ваша страница отобразит представление, которое использует этот пакет, оно отправит тег script, который браузер клиента не найдет в его кеш (поскольку строка запроса отличается).
Итак, похоже, что это решит вашу проблему - зависит от того, что вы подразумеваете под:
и они не изменят URL-адрес, указывающий на мой пакет, каждый раз, когда я меняю это
Ответ 3
Хотя нет лучшего способа настройки кеширования пакетов, вы можете создать HttpModule, который идентифицирует запросы к набору и задает кеширование содержимого.
У вас есть тот же эффект, что и на Global.asax:
public override void Init()
{
this.EndRequest += MvcApplication_EndRequest;
base.Init();
}
void MvcApplication_EndRequest(object sender, EventArgs e)
{
var request = this.Request;
var response = this.Response;
if (request.RawUrl.Contains("Content/"))
{
response.Cache.SetCacheability(HttpCacheability.NoCache);
}
}
Ответ 4
Кажется, что для меня работает пакет, содержащий номер версии в конфигурации пакета, а затем ссылку на новую версию в вашей разметке.
Ответ 5
Передайте дополнительный строковый параметр запроса в URL-адрес и измените его, когда вы хотите обновить кеш.
например: https://www.google.co.in/?gfe_rd=cr&ei=EwJeVbHWLcX08wfgwoCoBA&gws_rd=ssl&custom=abc
последний параметр является обычным.