Очистить кеш в MVC довольно просто — просто используйте связку .NET MVC для обнаружения изменений и добавления уникального идентификатора к вашим бандлам.
Однако все становится сложнее, когда пользователи не всегда обновляются. Рассмотрим следующий сценарий:
- Фрэнк посещает FStop.fm и загружает SPA FStop v1.0 с вашего сайта в свой браузер. Он использует его без перерыва, не обновляя браузер, потому что ваше приложение потрясающее.
- Вы отправляете обновление, FStop v1.1.
- Фрэнк не обновлял свой браузер год, потому что он был приклеен к FStop.
- Код Фрэнка на стороне клиента версии 1.0 отправляет запрос к конечным точкам API версии 1.1, которые доставляют полезные данные версии 1.1. Приложение Фрэнка выходит из строя или падает.
Как предотвратить это? Оказывается, это не так уж и плохо. Нам нужен какой-то способ, чтобы ваш SPA знал, какая у него версия клиентского кода. Затем нам нужно добавить номер версии к ответам AJAX, которые возвращает наш API. Наконец, нам нужно сравнить их при каждом ответе на клиенте, и если они отличаются, сообщить Фрэнку, что в его интересах перезагрузить его, когда у него будет такая возможность.
Часть 1. Какая у меня версия браузера?
Ваш код должен знать, какая у него версия. Итак, как часть каждой начальной полезной нагрузки, которая отправляется с вашим SPA, добавьте BuildVersion
:
// C# ViewModel viewModel.VersionNumber = Assembly.GetExecutingAssembly().GetName().Version.ToString();
Затем сериализуйте это в контексте вашего приложения, когда оно попадет в браузер на вашем Index.cshtml
:
<script type="text/javascript"> window.appContext = @Html.Raw(JsonConvert.SerializeObject(Model)) </script>
Теперь ваши клиентские модели просмотра и сервисы имеют доступ к кешированной версии.
Часть 2. Как сообщить клиенту, что доступна новая версия?
Теперь ваши запросы WebAPI нужно немного украсить версиями. Это было достигнуто путем создания пользовательского фильтра и его глобальной регистрации:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { var version = Assembly.GetExecutingAssembly().GetName().Version; actionExecutedContext.Response.Content.Headers.Add("BuildVersion", version.ToString()); }
Ответы от сервера будут содержать этот заголовок:
Часть 3. Как решить, когда уведомлять пользователя?
Ваше приложение должно запрашивать это при каждом последующем запросе AJAX, которое оно делает, читая значение заголовка, которое мы только что создали. Итак, в вашей базовой службе AJAX (или откуда бы ни отправлялись ваши запросы — надеюсь, не из множества мест) выполните проверку, подобную следующей:
if (!warned){ var newVersionNumber = response.getResponseHeader("BuildVersion"); if (newVersionNumber != cachedVersionNumber){ doSomething(); } }
Это означает, что если приложение выдает ошибку из-за несоответствия, вы принудительно обновляете его. В противном случае просто скажите Фрэнку один раз, что могут быть некоторые ошибки, если он не обновится.
Спасибо за чтение!
Мик