Кеширование полного ответа на сервере - PullRequest
9 голосов
/ 09 мая 2020

Вот очень маленький образец страницы Razor:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<h1>
    @DateTime.Now.ToString()
</h1>

//model
public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;

    public IndexModel(ILogger<IndexModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {

    }
}

Если я использую этот код, время будет обновляться каждые 30 секунд, что и предполагалось:

<cache expires-after="TimeSpan.FromSeconds(30)">
    <h1>
        @DateTime.Now.ToString()
    </h1>
</cache>

Однако, добавление атрибута ResponseCache к модели этого не делает:

[ResponseCache(Duration = 30)]
public class IndexModel : PageModel

После некоторого исследования кажется, что атрибут только отправляет клиенту соответствующие заголовки, прося его кэшировать содержимое. Как я могу сохранить весь ответ в памяти, чтобы, когда пользователь запрашивает определенную страницу c, сервер просто отправляет кэшированный ответ и снова исключает процесс вычисления результата?

Кроме того, с помощью <cache> tag helper, я не смог найти способ сделать запись в кэше недействительной. Таким образом, одним из сценариев для меня было бы кэшировать каждую страницу в памяти в течение 30 дней, и если я что-то изменю в панели администратора, я бы тогда сделал недействительным кеш для этого элемента c, чтобы следующий запрос выдал fre sh результат. Раньше я делал это на Asp. Net MVC 3+, но не мог найти никакого метода для достижения того же результата в Asp. Net Core 3.1

Ответы [ 2 ]

1 голос
/ 25 мая 2020

Из вашего вопроса кажется, что вам может потребоваться развернуть свою собственную версию

Как я могу сохранить весь ответ в памяти, чтобы, когда пользователь запрашивает конкретную страницу c, сервер просто отправляет кешированный ответ и снова исключает процесс вычисления результата?

См. источник https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.Core/src/ResponseCacheAttribute.cs

И

https://github.com/aspnet/Mvc/blob/d8c6c4ab34e1368c1b071a01fcdcb9e8cc12e110/src/Microsoft.AspNetCore.Mvc.Core/Internal/ResponseCacheFilter.cs

Похоже, устанавливает только заголовки.

Вы можете реализовать свою собственную версию кэширования, подобную этой

https://www.devtrends.co.uk/blog/custom-response-caching-in-asp.net-core-with-cache-invalidation

См. CachedPage класс в примере выше .

0 голосов
/ 22 мая 2020

Edit: Нет, это не работает (я не могу удалить этот ответ).

https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/performance/caching/middleware/samples/3.x/ResponseCachingMiddleware

Браузеры часто добавляют заголовок управления кешем при перезагрузке, что не позволяет промежуточному программному обеспечению обслуживать кешированную страницу.

Следовательно, это не работает, и я не понимаю, как это может быть полезно, кроме запросов машина-машина с использованием специально созданных запросов.

Используйте инструмент разработчика, который позволяет устанавливать заголовки запросов явно, например Fiddler или Postman.


Я еще не тестировал его, но похоже, что «промежуточное ПО кэширования ответов» могло бы быть ответом.

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-3.1

Для кэширования на стороне сервера, которое соответствует спецификации кэширования HTTP 1.1, используйте ПО промежуточного слоя кэширования ответов. По промежуточного слоя можно использовать свойства ResponseCacheAttribute, чтобы влиять на поведение кэширования на стороне сервера.

ПО промежуточного слоя кэширования ответов в ASP. NET Ядро:

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-3.1

Промежуточное ПО определяет, когда ответы кэшируются, сохраняет ответы и обслуживает ответы из кеша.

Однако вы не всегда получите кешированный ответ.

ПО промежуточного слоя соблюдает правила спецификации кэширования HTTP 1.1. Правила требуют, чтобы кеш соблюдал допустимый заголовок Cache-Control, отправленный клиентом. Согласно спецификации, клиент может делать запросы со значением заголовка без кеширования и заставлять сервер генерировать новый ответ на каждый запрос. В настоящее время разработчик не может контролировать это поведение кэширования при использовании промежуточного программного обеспечения, поскольку промежуточное программное обеспечение соответствует официальной спецификации кэширования.

Кроме того,

Кэширование следует включать только для содержимое, которое не изменяется в зависимости от личности пользователя или от того, вошел ли пользователь в систему.

...