Как заставить Firefox не кэшировать или повторно загружать XAP-файл Silverlight?

При работе с Silverlight я заметил, что Firefox кэширует файл XAP, поэтому, если я сделаю обновление, пользователь может застрять в использовании устаревшей версии. Есть ли способ заставить браузер либо повторно загружать файл XAP каждый раз, либо только после публикации обновления? Или в конфигурации Silverlight есть параметр, который запрещает браузеру полностью кэшировать файл XAP?

Спасибо Джефф


person Yttrium    schedule 21.11.2008    source источник
comment
У меня тоже есть эта проблема. Думал, что изменения моей страницы не сработали, оказалось, что я смотрел кешированную версию. Раздражающий.   -  person jcollum    schedule 26.02.2009
comment
У меня проблема при использовании трюков с кешем ниже на SL5, которые работали на SL4, мой вопрос здесь: stackoverflow.com/questions/8974957/   -  person jv42    schedule 23.01.2012
comment
Я добавил награду к моему вопросу SL5, похоже, особого внимания не уделяется (stackoverflow.com/questions/8974957/). Если люди успешно использовали подобный прием со средой выполнения SL5, меня это интересует!   -  person jv42    schedule 22.04.2012


Ответы (17)


Строка запроса работает отлично, но я бы не стал использовать DateTime.Now, потому что он заставляет пользователя каждый раз повторно загружать приложение. Вместо этого мы используем следующее:

protected void Page_Load(object sender, EventArgs e)
{
    var versionNumber = Assembly.GetExecutingAssembly().GetName().Version.ToString();
    this.myApp.Source += "?" + versionNumber;
}

Таким образом, все, что вам нужно сделать, это увеличить номер версии в файле AssemblyInfo.cs.

person Romain    schedule 24.09.2009
comment
является ли этот обработчик события Page_Load обработчиком события страницы или представления silverlight? - person bleepzter; 14.09.2011
comment
Это со страницы ASP.NET, содержащей ‹object› Silverlight. - person jv42; 09.11.2011

Самый простой способ:

<param name="source" value="ClientBin/App.xap?<%= DateTime.Now.Ticks %>" />
person Andy Mehalick    schedule 02.09.2009
comment
Было бы гораздо лучше взять дату файла xap. Тогда пользователям не нужно было бы скачивать приложение каждый раз. - person FlappySocks; 10.12.2009
comment
Как сделать это из внутреннего кода и вставить его на html-страницу вместо DateTime? Пример пожалуйста. - person Stephen Price; 09.06.2010
comment
Вы можете дать элементу param идентификатор и атрибут runat = server для доступа к нему в коде позади. Предполагая, что id = SourceParam: SourceParam.Attributes [значение] + =? + DateTime.Today.Ticks; - person Andy Mehalick; 03.07.2010

Это то, что я делаю в php. Вы читаете дату / время файла xap и добавляете его в качестве параметра к ссылке для скачивания. Таким образом, браузер видит новые версии файлов как новые ссылки и, следовательно, не в своем кеше.

<?php $fdate = date("dHis",filemtime("MyApp.xap")) ?>

<param name="source" value="MyApp.xap?=<?php echo $fdate ?>"/>

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

person FlappySocks    schedule 10.12.2009

Возможно, вам будет полезно Руководство по кешированию для авторов и веб-мастеров. В этом документе обсуждаются различные кеши, через которые взаимодействуют клиент и сервер (браузер, прокси, шлюз), и способы управления кешированием.

person converter42    schedule 21.11.2008
comment
Как это отвечает на вопрос? Он не решает конкретных проблем файлов XAP. - person KevDog; 02.09.2009
comment
KevDog: Если, как говорит Тимоти Ли Рассел в своем ответе, очистка кеша Firefox исправляет это, то это означает, что Firefox (а не плагин Silverlight) запрашивает файл через HTTP, как и любой другой веб-ресурс, и кэширует его, используя те же правила. которые применяются ко всему контенту. Понимание правил кеширования может помочь. - person Jason Orendorff; 10.12.2009

Для меня лучший ответ - от Крис Кэрнс. Я просто немного адаптировал его, вызвав ToString и GetHashCode, сгенерировав идентификатор для временной метки:

<param name="source" value="ClientBin/App.xap?<%= System.IO.File.GetLastWriteTime(Server.MapPath("ClientBin/App.xap")).ToString().GetHashCode()%>" />

Работает отлично!

person JwJosefy    schedule 10.06.2011

Вы можете отправить заголовки HTTP, чтобы предотвратить его кеширование:

Cache-control: no-cache
Pragma: no-cache

Как вы это делаете, зависит от используемого вами веб-сервера.

person Jarett Millard    schedule 21.11.2008
comment
Тимоти: Вы должны убедиться, что эти HTTP-заголовки относятся к XAP-файлу, а не к HTML-странице. IIS позволяет настраивать пользовательские заголовки для каждой папки: support.microsoft.com/kb/247404 - person Jason Orendorff; 10.12.2009
comment
если ваши пользователи загружают один и тот же точный код каждый раз, когда они посещают ваше приложение silverlight, особенно когда у вас нет изменений ... я собираюсь рискнуть и сказать, что вы делаете это неправильно. - person felickz; 24.04.2012

Другое решение - добавить версию файла XAP, а не метку времени. Отметка времени будет меняться каждый раз (с таким же успехом можно отключить кеширование). Чтобы заставить его изменяться только после обновления XAP, нужно взять некоторую информацию из файла XAP. Я все еще ищу то, что я мог бы использовать, возможно, последнюю измененную дату в XAP-файле?

person Stephen Price    schedule 10.07.2009
comment
Это лучшее решение. Безумие заставлять пользователя каждый раз загружать приложение, используя случайный URL-адрес. - person FlappySocks; 10.12.2009

Добавление метки времени для XAP сработало для меня (я добавляю элемент управления SL в javascript, но это так же легко можно сделать встроенным):

var appTimestamp = '<%= System.IO.File.GetLastWriteTime(Server.MapPath("ClientBin/MyApp.xap")) %>';
var source = 'ClientBin/MyApp.xap?appTimestamp=' + appTimestamp;
person Chris Cairns    schedule 27.10.2010

Это протестировано и работает:

Положи это:

<%
    const string sourceValue = @"ClientBin/MyXapFile.xap";
    string param;

    if(System.Diagnostics.Debugger.IsAttached)
        param = "<param name=\"source\" value=\"" + sourceValue + "\" />";
    else
    {
        var xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + sourceValue;
        var xapCreationDate = System.IO.File.GetLastWriteTime(xappath);

        param = "<param name=\"source\" value=\"" + sourceValue + "?ignore="
        + xapCreationDate + "\" />";
    }
    Response.Write(param);
%>

Вместо этого:

<param name="source" value="ClientBin/MyXapFile.xap" />
person Alexanderius    schedule 08.11.2011

Я заставляю это работать с помощью комбинации приведенных выше предложений:

  1. Установите для атрибутов метатега cache-control / pragma http-Equiv значение 'No-Cache'
  2. Используйте страницу ASP.NET для размещения элемента управления silverlight (в отличие от страницы html)
  3. Задайте свойство Source элемента управления ASP.NET Silverlight в коде позади, добавив отметку времени к URL-адресу .xap, например.

    Silverlight1.Source = "ClientBin / MyApplication.xap?" + DateTime.Now.ToString ("дд-ММ-гг-ЧЧ: мм: сс");

person Community    schedule 28.05.2009

Вы можете добавить URL-адрес источника в тег объекта с датой последней записи XAP-файла. Проверьте код в моем блоге.

person Lars Holm Jensen    schedule 01.02.2010

Мы также находимся в той же ситуации, когда хотим контролировать, когда файл .XAP загружается в браузер.

Подход, на который вы, возможно, захотите взглянуть, - это использование изолированного хранилища Silverlight в качестве «кеша» для хранения ваших файлов .XAP.

Посетите этот блог: IsolatedStorage как объект Silverlight кеш

person ptio    schedule 21.11.2008
comment
Хотя это действительно меняет способ сохранения кеша, это не дает способа узнать, было ли выполнено обновление на сервере, и это связано с тем, что код Silverlight запускается на клиенте и не знает о файле на сервер. Вам нужно будет использовать Isostorage для управления датой загруженных сборок. - person Gabriel Guimarães; 25.05.2010

Супер простая идея: просто добавьте к URL-адресу фальшивую строку запроса.

<param name="source" value="app.xap?r12345"/>

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

В идеале ваш сервер должен делать это за вас. Но если нет ...

person Kevin Moore    schedule 21.11.2008
comment
Он будет работать в первый раз, но не при последующих запросах, значение строки запроса должно быть динамическим. - person KevDog; 02.09.2009

У меня была эта проблема, поэтому теперь, когда я запускаю новое приложение, я устанавливаю версию сборки на 0.0.0.1 и просто обновляю ее по одному при каждом развертывании, похоже, это решило для меня. Затем просто установите его обратно на 1.0.0.0 при выпуске.

person David Casey    schedule 26.11.2008

Пока что единственное решение, которое я нашел, когда проблема возникает, - это очистить кеш Firefox.

Лучшее решение было бы намного лучше.

person Timothy Lee Russell    schedule 23.01.2009
comment
Это важно, т.к. это единственный способ исправить проблему. Вместо того, чтобы сосредоточиться на предотвращении проблемы. Есть некоторые данные, которые вы хотите нормально кэшировать ... но как разработчик вы хотите получить новую копию. - person ftrotter; 28.07.2010

Я использую это решение

<object id="Xaml1" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
width="100%" height="100%">
<%––<param name="source" value="ClientBin/SilverlightApp.xap"/>––%>
<%
string orgSourceValue = @"ClientBin/SilverlightApp.xap";
string param;
if (System.Diagnostics.Debugger.IsAttached)
param = "<param name=\"source\" value=\"" + orgSourceValue + "\" />";
else
{
string xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + orgSourceValue;
DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
param = "<param name=\"source\" value=\"" + orgSourceValue + "?ignore="
+ xapCreationDate.ToString() + "\" />";
}
Response.Write(param);
%>
<param name="onError" value="onSilverlightError" 
person Vladimir Dorokhov    schedule 01.09.2011

Идея строки запроса не работает для меня в Silverlight 4. Сервер, кажется, кэширует проклятый xap (но не файл aspx). Решение, которое действительно работает в SL4, - это перейти к свойствам вашего проекта Silverlight, перейти к информации о сборке и ввести версию.

person Chris Bordeman    schedule 26.05.2010