OutputCache не работает, если кодировка содержимого добавлена ​​в заголовок - PullRequest
0 голосов
/ 06 июня 2018

У меня есть контроллер и действие в нем.

public class LoginController
{
    [OutputCache(Duration = 10000, VaryByParam = "none")]
    public ActionResult Logout()
    {
        ......
    }
}

Над кодом работает, и нет проблем с выходным кешем.Все в порядке.

Но когда я добавил приведенный ниже код в Application_BeginRequest, что-то пошло не так.Я добавил изображение страницы.

 string encodings = app.Request.Headers.Get("Accept-Encoding");
 if (encodings != null)
 {
            // Check the browser accepts deflate or gzip (deflate takes preference)
            encodings = encodings.ToLower();

            if (encodings.Contains("gzip"))
            {
                app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "gzip");
            }
            else if (encodings.Contains("deflate"))
            {
                app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "deflate");
            }

 }

The page is ....

1 Ответ

0 голосов
/ 22 июня 2018

Вы должны добавить VaryByContentEncoding.
Без него кэшируется только 1 версия.

Если эта версия в кеше создана из запроса, поддерживающего, например,.Сжатие gzip, эти кэшированные данные будут сжаты в формате gzip.
Эти же сжатые данные затем будут также передаваться запросам, которые не поддерживают сжатие или только выкачивают, что приводит к тому, что вы видите.

Вы должны убедиться, что отдельные версии кэшируются;1 несжатый, 1 для gizp и другой для deflate.
Это позволяет предоставлять правильную версию в соответствии с тем, что поддерживает веб-браузер.

[OutputCache(Duration = 10000, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
public ActionResult Logout()
{
    // ...
}

EDIT

Помимо пропущенного VaryByContentEncoding, происходит еще больше.

Application_BeginRequest не «хорошо играет» с OutputCacheAttribute.
Из-за этого продолжительность кеша не увеличиваетсябольше не применяется.Это должно быть связано с порядком выполнения и тем, какие заголовки установлены в какой момент.

Вместо того, чтобы полагаться на Application_BeginRequest, переместите код сжатия в фильтр действий, который для ASP.NET MVC является рекомендуемым способом.действовать в конвейере запросов.
См. CompressAttribute ниже.

В качестве примера я применил его к готовому About методу HomeController.
На этот раз ожидаемые результаты соответствуют заголовкам http запроса и ответа.

CompressAttribute:

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
        HttpResponseBase response = filterContext.RequestContext.HttpContext.Response;

        string encodings = request.Headers.Get("Accept-Encoding");
        if (encodings != null)
        {
            // Check the browser accepts deflate or gzip (deflate takes preference)
            encodings = encodings.ToLower();

            if (encodings.Contains("gzip"))
            {
                response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                response.AppendHeader("Content-Encoding", "gzip");
            }
            else if (encodings.Contains("deflate"))
            {
                response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                response.AppendHeader("Content-Encoding", "deflate");
            }
        }
    }
}

HomeController:

public class HomeController : Controller
{
    [Compress()]
    [OutputCache(Duration = 10, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
    public ActionResult About()
    {
        ViewBag.Message = DateTime.Now.ToString("dd/MM/yy HH:mm:ss.fff");
        return View();
    }        
}
...