Очистить кеш в MVC довольно просто — просто используйте связку .NET MVC для обнаружения изменений и добавления уникального идентификатора к вашим бандлам.

Однако все становится сложнее, когда пользователи не всегда обновляются. Рассмотрим следующий сценарий:

  1. Фрэнк посещает FStop.fm и загружает SPA FStop v1.0 с вашего сайта в свой браузер. Он использует его без перерыва, не обновляя браузер, потому что ваше приложение потрясающее.
  2. Вы отправляете обновление, FStop v1.1.
  3. Фрэнк не обновлял свой браузер год, потому что он был приклеен к FStop.
  4. Код Фрэнка на стороне клиента версии 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();
  }
}

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

Спасибо за чтение!

Мик