forza i browser a ottenere i file js e css più recenti nell'applicazione asp.net


104

Alcuni browser memorizzano nella cache i file js e css, non riuscendo ad aggiornarli a meno che tu non li costringa a farlo. Qual è il modo più semplice.

Ho appena implementato questa soluzione che sembra funzionare.

Dichiara una variabile di versione sulla tua pagina

  public string version { get; set; }

Ottieni il numero di versione dalla chiave web.config

 version = ConfigurationManager.AppSettings["versionNumber"];

Nella tua pagina aspx effettua le chiamate a javascript e fogli di stile in questo modo

<script src="scripts/myjavascript.js?v=<%=version %>" type="text/javascript"></script>
<link href="styles/mystyle.css?v=<%=version %>" rel="stylesheet" type="text/css" />

Quindi, se imposti la versione = 1.1 da 1.0 nel tuo web.config, il tuo browser scaricherà i file più recenti che, si spera, salveranno te e i tuoi utenti un po 'di frustrazione.

C'è un'altra soluzione che funziona meglio o questo causerà problemi imprevisti a un sito web?


Domanda interessante, ho avuto lo stesso problema di recente, ma è stato solo un problema durante i test di sviluppo. Non ci siamo preoccupati molto perché non intendiamo modificare quei file dopo il lancio. Mi piacerebbe conoscere una soluzione anche se per riferimento futuro!
Brett Allen

L'unico problema che posso vedere è che le modifiche al web.config chiameranno, in background, il riavvio di un'applicazione: msdn.microsoft.com/en-us/library/aa478432.aspx
monty

Grazie per la domanda. Questo mi ha aiutato a risolvere un grosso problema.
Reddy

Risposte:


76

Ho risolto questo problema aggiungendo un timestamp dell'ultima modifica come parametro di query agli script.

L'ho fatto con un metodo di estensione e utilizzandolo nei miei file CSHTML. Nota: questa implementazione memorizza nella cache il timestamp per 1 minuto in modo da non eseguire il thrash del disco così tanto.

Ecco il metodo di estensione:

public static class JavascriptExtension {
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;

        if (context.Cache[filename] == null)
        {
            var physicalPath = context.Server.MapPath(filename);
            var version = $"?v={new System.IO.FileInfo(physicalPath).LastWriteTime.ToString("MMddHHmmss")}";
            context.Cache.Add(filename, version, null,
              DateTime.Now.AddMinutes(5), TimeSpan.Zero,
              CacheItemPriority.Normal, null);
            return version;
        }
        else
        {
            return context.Cache[filename] as string;
        }
    }
}

E poi nella pagina CSHTML:

 @Html.IncludeVersionedJs("/MyJavascriptFile.js")

Nell'HTML visualizzato, appare come:

 <script type='text/javascript' src='/MyJavascriptFile.js?20111129120000'></script>

1
questo è ottimo per mvc, mi chiedo se l'ultimo framework mvc 5 gestisca questo problema? L'approccio utilizzato dal raggruppamento con - {version} jolly è anche un modo per risolvere questo problema, tuttavia richiede che i file vengano rinominati dopo ogni nuova build ...
kiev

Sto usando le basi del tuo esempio MVC in un sito Web di moduli web e funziona alla grande, quindi grazie per la condivisione!
Bryan

È necessario preoccuparsi della visualizzazione dell'ultima modifica data / ora per i file di risorse? Se un file in uso avesse una data / ora di qualche anno fa, potrebbero essere informazioni che un'azienda potrebbe non voler rendere pubbliche ai propri utenti?
Bryan

È il modo standard, seguono principalmente le applicazioni. Ma quel timestamp dovrebbe cambiare solo quando si distribuisce o si crea l'applicazione. Altrimenti ogni volta che l'utente aggiorna la pagina o passa ad altre pagine nella tua applicazione. Il browser scaricherà di nuovo tutti i fogli di stile e javascript, il che non va bene
Tarun

2
Qual è l'impatto sulle prestazioni della pagina? Quanto ritardo può causare il caricamento della pagina?
Durgesh Sonawane

28

La tua soluzione funziona. In effetti è abbastanza popolare.

Anche Stack Overflow utilizza un metodo simile:

<link rel="stylesheet" href="http://sstatic.net/so/all.css?v=6184"> 

Dov'è v=6184probabilmente il numero di revisione SVN.


Questo sarebbe un approccio molto più faticoso di quello descritto nella risposta accettata. Controllare la versione SVN del file ogni volta che viene pubblicata una pagina è un sovraccarico delle prestazioni, soprattutto perché il numero di utenti aumenta nel tempo.
Neolisk

4
È possibile ottenere il numero di revisione durante la compilazione, scriverlo in un file (ad esempio un file .cs parziale), includere quel file nel progetto, quindi non è necessario leggerlo da svn in fase di esecuzione. Ho usato questo approccio con msbuild per inserire i numeri di revisione nei miei file AssemblyInfo.cs da svn.
Ramazan Binarbasi

2
L'utilizzo di un numero di versione / revisione globale ha almeno uno svantaggio: la pubblicazione di un aggiornamento del sito Web invalida le cache del browser per tutti i file .js e .css, non solo per quelli modificati. Questo probabilmente non ha importanza nella maggior parte delle applicazioni, ma lo menziono per completezza.
Adam Tegen

Se aggiorni automaticamente la versione dei tuoi file assemblyinfo.cs durante una distribuzione o compilazione, per quel numero potrebbe essere utilizzata la versione secondaria.
kristianp

28

In ASP.NET Core (MVC 6) funziona immediatamente tramite il asp-append-versiontag helper:

<script src="scripts/myjavascript.js" asp-append-version="true"></script>
<link href="styles/mystyle.css rel="stylesheet" asp-append-version="true" />

1
Grazie per averci fatto sapere! Non lo sapevo prima!
Federico Navarrete

18

ASP.NET MVC gestirà questo per te se usi bundle per il tuo JS / CSS. Aggiungerà automaticamente un numero di versione sotto forma di GUID ai tuoi bundle e aggiornerà questo GUID solo quando il bundle viene aggiornato (ovvero tutti i file di origine hanno modifiche).

Questo aiuta anche se hai un sacco di file JS / CSS in quanto può migliorare notevolmente i tempi di caricamento dei contenuti!

Vedere qui


Vuoi dire che se usiamo bundle in un'applicazione MVC, non c'è bisogno di nessuno dei metodi nella risposta pubblicata qui? Se è così, il raggruppamento è davvero molto più importante che abbia mai pensato. Potrebbe chiarirci questo problema? Grazie.
Jack

1
Si, esattamente. Finché i tuoi script sono inclusi in un pacchetto, genererà automaticamente un numero di versione per ogni pacchetto quando vengono rilevate modifiche in uno qualsiasi dei file di origine del pacchetto.
jonesy827

E non dimenticare che hai ancora mal di testa come sviluppatore. Il raggruppamento ASP.NET non aiuta in alcun modo durante il debug e lo sviluppo.
it3xl

12

C'è un modo integrato in asp.net per questo: raggruppamento . Usalo e basta. Ogni nuova versione avrà il suffisso univoco "? V = XXXXXXX". In modalità debug il raggruppamento è disattivato, per attivare l'impostazione make in web.config:

<system.web>
    <compilation debug="false" />
</system.web>

Oppure aggiungi al metodo RegisterBundles (BundleCollection bundles):

BundleTable.EnableOptimizations = true;

Per esempio:

BundleConfig.cs:

bundles.Add(new ScriptBundle("~/Scripts/myjavascript.js")
                .Include("~/Scripts/myjavascript.js"));

bundles.Add(new StyleBundle("~/Content/mystyle.css")
                .Include("~/Content/mystyle.css"));

_Layout.cshtml:

@Scripts.Render("~/Scripts/myjavascript.js")
@Styles.Render("~/Content/mystyle.css")

Ma questo funzionerà solo in ambienti di rilascio o di produzione. E lo sviluppo quando è attiva la modalità di debug? Il bundle risolve ancora questo problema?
VAAA

Sì, bundlind non rende gli sviluppatori più facili da vivere. Devi premere Ctrl-F5 dopo ogni modifica dello script. E se hai le cornici sarà ancora più divertente.
it3xl

6

C'è una risposta più semplice a questa rispetto alla risposta data dall'op nella domanda (l'approccio è lo stesso):

Definisci la chiave nel web.config:

<add key="VersionNumber" value="06032014"/>

Effettua la chiamata a appsettings direttamente dalla pagina aspx:

<link href="styles/navigation.css?v=<%=ConfigurationManager.AppSettings["VersionNumber"]%>" rel="stylesheet" type="text/css" />

Mi piace, ma sono preoccupato perché questa soluzione ha così pochi voti
positivi

@SimplyInk Non lo so, ma ci sono 20 risposte diverse, quindi questo potrebbe avere qualcosa a che fare con esso. Se funziona e ti piace, sentiti libero di votarlo.
JackArbiter,

4

Basato sulla risposta di Adam Tegan , modificato per l'uso in un'applicazione di moduli web.

Nel codice della classe .cs:

public static class FileUtility
{
    public static string SetJsVersion(HttpContext context, string filename) {
        string version = GetJsFileVersion(context, filename);
        return filename + version;
    }

    private static string GetJsFileVersion(HttpContext context, string filename)
    {
        if (context.Cache[filename] == null)
        {
            string filePhysicalPath = context.Server.MapPath(filename);

            string version = "?v=" + GetFileLastModifiedDateTime(context, filePhysicalPath, "yyyyMMddhhmmss");

            return version;
        }
        else
        {
            return string.Empty;
        }
    }

    public static string GetFileLastModifiedDateTime(HttpContext context, string filePath, string dateFormat)
    {
        return new System.IO.FileInfo(filePath).LastWriteTime.ToString(dateFormat);
    }
}

Nel markup aspx:

<script type="text/javascript" src='<%= FileUtility.SetJsVersion(Context,"/js/exampleJavaScriptFile.js") %>'></script>

E nell'HTML renderizzato, appare come

<script type="text/javascript" src='/js/exampleJavaScriptFile.js?v=20150402021544'></script>

2
Hey! Il tuo esempio funziona, ma dovresti rimuovere i riferimenti di memorizzazione nella cache o correggere il codice per utilizzare la cache perché può confondere il motivo per cui lo stai usando. Per utilizzare la cache è necessario aggiungere la versione del file alla cache utilizzando il metodo context.Cache.Add nel case context.Cache [filename] == null. Se context.Cache [filename]! = Null, dovresti restituire il valore memorizzato nella cache (context.Cache [filename])
Flavia Obreja

1
Flavia, penso che la tua spiegazione abbia un senso e penso che sia un'implementazione più semplice ed efficiente. Grazie per aver pubblicato commenti e feedback utili.
Bryan

4

È interessante notare che questo stesso sito ha problemi con l'approccio che descrivi in ​​relazione ad alcune configurazioni proxy, anche se dovrebbe essere a prova di errore.

Controlla questa discussione su Meta Stack Overflow .

Quindi, alla luce di ciò, potrebbe avere senso non utilizzare un parametro GET per l'aggiornamento, ma il nome del file effettivo:

href="/css/scriptname/versionNumber.css" 

anche se questo è più lavoro da fare, poiché dovrai effettivamente creare il file o costruire una riscrittura dell'URL per esso.


4

Volevo un semplice liner per rendere il percorso unico per rompere la cache. Questo ha funzionato per me:

<script src="scripts/main.js?bust_js_cache=<%=System.IO.File.GetLastWriteTime(Server.MapPath("scripts/main.js")).ToString("HH:mm:ss")%>" type="text/javascript"></script>

Se il file è stato modificato dall'ultima volta che è stato caricato nella pagina, il browser estrarrà il file aggiornato.

Genera il last modifiedtimbro dal .jsfile e lo inserisce lì invece della versione a cui potrebbe non essere facile accedere.

<script src="scripts/main.js?bust_js_cache=10:18:38" type="text/javascript"></script>

Un'altra opzione potrebbe essere quella di ottenere il checksum del file.


1
Di gran lunga il modo più semplice per farlo, e probabilmente il sovraccarico più basso.
Tony Hinkle

1
Soluzione perfetta. Ho anche testato Chrome 70, Firefox 63 e IE 11 per assicurarmi che il caching funzionasse effettivamente. È. Questo interrompe la memorizzazione nella cache solo sulle nuove versioni del file, almeno sulle ultime versioni dei browser. Ho sentito dire altrove che alcuni browser ricaricano ogni file con una querystring (?). Forse era così o forse è ancora vero con Safari e Opera. DK.
Brad Mathews

3

Ecco un approccio che funziona con ASP.NET 5 / MVC 6 / vNext .

Passaggio 1: creare una classe per restituire l'ora dell'ultima scrittura del file, simile ad altre risposte in questo thread. Nota, questo richiede l'inserimento di dipendenze ASP.NET 5 (o altro).

public class FileVersionService
{
    private IHostingEnvironment _hostingEnvironment;
    public FileVersionService(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public string GetFileVersion(string filename)
    {
       var path = string.Format("{0}{1}", _hostingEnvironment.WebRootPath, filename);
       var fileInfo = new FileInfo(path);
       var version = fileInfo.LastWriteTimeUtc.ToString("yyyyMMddhhmmssfff");
       return version;
     }
}

Passaggio 2: registrare il servizio da inserire in startup.cs :

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<FileVersionService>();
    ...
}

Passaggio 3: quindi, in ASP.NET 5, è possibile inserire il servizio direttamente in una visualizzazione layout come _Layout.cshtml in questo modo:

@inject Namespace.Here.FileVersionService fileVersionService
<!DOCTYPE html>
<html lang="en" class="@ViewBag.HtmlClass">
<head>
    ...
    <link href="/css/styles.css?v=@fileVersionService.GetFileVersion("\\css\\styles.css")" rel="stylesheet" />
    ...
</head>
<body>
    ...
</body>

Ci sono alcuni ritocchi finali che potrebbero essere fatti per combinare meglio i percorsi fisici e gestire il nome del file in uno stile più coerente con la sintassi, ma questo è un punto di partenza. Spero che aiuti le persone a passare a ASP.NET 5.


questo comportamento è effettivamente supportato immediatamente, vedere la mia risposta
metalheart

3

Ho impiegato una tecnica leggermente diversa nel mio sito aspnet MVC 4:

_ViewStart.cshtml:

@using System.Web.Caching
@using System.Web.Hosting
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    PageData.Add("scriptFormat", string.Format("<script src=\"{{0}}?_={0}\"></script>", GetDeployTicks()));
}

@functions
{

    private static string GetDeployTicks()
    {
        const string cacheKey = "DeployTicks";
        var returnValue = HttpRuntime.Cache[cacheKey] as string;
        if (null == returnValue)
        {
            var absolute = HostingEnvironment.MapPath("~/Web.config");
            returnValue = File.GetLastWriteTime(absolute).Ticks.ToString();
            HttpRuntime.Cache.Insert(cacheKey, returnValue, new CacheDependency(absolute));
        }
        return returnValue;
    }
}

Quindi nelle visualizzazioni effettive:

 @Scripts.RenderFormat(PageData["scriptFormat"], "~/Scripts/Search/javascriptFile.min.js")

3

<?php $rand_no = rand(10000000, 99999999)?> <script src="scripts/myjavascript.js?v=<?=$rand_no"></script>

Questo funziona per me in tutti i browser. Qui ho usato PHP per generare casuali no. Puoi usare la tua lingua lato server


Bella risposta, ma ASP MVC può essere un po 'problematico se non si considera ciò che ha spiegato Adam perché l'ho provato e la cartella Bundle non lo riconosce se si lavora con MVC 5. Ma grazie per il suggerimento!
Federico Navarrete

2

Partendo dalla risposta sopra ho modificato un po 'il codice per far funzionare anche l'helper con i file CSS e aggiungere una versione ogni volta che si apportano modifiche ai file e non solo quando si esegue la compilazione

public static class HtmlHelperExtensions
{
    public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename)
    {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
    }

    public static MvcHtmlString IncludeVersionedCss(this HtmlHelper helper, string filename)
    {
        string version = GetVersion(helper, filename);
        return MvcHtmlString.Create("<link href='" + filename + version + "' type ='text/css' rel='stylesheet'/>");
    }

    private static string GetVersion(this HtmlHelper helper, string filename)
    {
        var context = helper.ViewContext.RequestContext.HttpContext;
        var physicalPath = context.Server.MapPath(filename);
        var version = "?v=" +
        new System.IO.FileInfo(physicalPath).LastWriteTime
        .ToString("yyyyMMddHHmmss");
        context.Cache.Add(physicalPath, version, null,
          DateTime.Now.AddMinutes(1), TimeSpan.Zero,
          CacheItemPriority.Normal, null);

        if (context.Cache[filename] == null)
        {
            context.Cache[filename] = version;
            return version;
        }
        else
        {
            if (version != context.Cache[filename].ToString())
            {
                context.Cache[filename] = version;
                return version;
            }
            return context.Cache[filename] as string;
        }
    }
}

1

Ottieni l'ora di modifica del file, come mostrato di seguito

private static string GetLastWriteTimeForFile(string pathVal)
    {
        return System.IO.File.GetLastWriteTime(HostingEnvironment.MapPath(pathVal)).ToFileTime().ToString();
    }

Aggiungi questo con input come querystring

public static string AppendDateInFile(string pathVal)
    {
        var patheWithDate = new StringBuilder(pathVal);
        patheWithDate.AppendFormat("{0}x={1}",
                               pathVal.IndexOf('?') >= 0 ? '&' : '?',
                               GetLastWriteTimeForFile(pathVal));
        return patheWithDate.ToString();
    }

Chiamalo da markup.

Approccio MVC Extension Helper

Aggiungi un metodo di estensione

namespace TNS.Portal.Helpers
{
    public static class ScriptExtensions
    {
        public static HtmlString QueryStringScript<T>(this HtmlHelper<T> html, string path)
        {
            var file = html.ViewContext.HttpContext.Server.MapPath(path);
            DateTime lastModified = File.GetLastWriteTime(file);
            TagBuilder builder = new TagBuilder("script");
            builder.Attributes["src"] = path + "?modified=" + lastModified.ToString("yyyyMMddhhmmss");
            return new HtmlString(builder.ToString());
        }

       public static HtmlString QueryStringStylesheet<T>(this HtmlHelper<T> html, string path)
       {
        var file = html.ViewContext.HttpContext.Server.MapPath(path);
        DateTime lastModified = File.GetLastWriteTime(file);
        TagBuilder builder = new TagBuilder("link");
        builder.Attributes["href"] = path + "?modified=" + lastModified.ToString("yyyyMMddhhmmss");
        builder.Attributes["rel"] = "stylesheet";
        return new HtmlString(builder.ToString());
      }

    }
}

Aggiungi questo spazio dei nomi in web.config

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="TNS.Portal" />
        <add namespace="TNS.Portal.Helpers" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Usalo in vista come

@Html.QueryStringScript("/Scripts/NPIAjaxCalls.js")
@Html.QueryStringStylesheet("/Content/StyledRadio.css")

1

Suggerimenti precedenti semplificati e fornitura di codice per gli sviluppatori di moduli Web .NET.

Ciò accetterà sia URL relativi ("~ /") e assoluti nel percorso del file alla risorsa.

Metti in un file di classe delle estensioni statiche, il seguente:

public static string VersionedContent(this HttpContext httpContext, string virtualFilePath)
{
    var physicalFilePath = httpContext.Server.MapPath(virtualFilePath);
    if (httpContext.Cache[physicalFilePath] == null)
    {
        httpContext.Cache[physicalFilePath] = ((Page)httpContext.CurrentHandler).ResolveUrl(virtualFilePath) + (virtualFilePath.Contains("?") ? "&" : "?") + "v=" + File.GetLastWriteTime(physicalFilePath).ToString("yyyyMMddHHmmss");
    }
    return (string)httpContext.Cache[physicalFilePath];
}

E poi chiamalo nella tua pagina master come tale:

<link type="text/css" rel="stylesheet" href="<%= Context.VersionedContent("~/styles/mystyle.css") %>" />
<script type="text/javascript" src="<%= Context.VersionedContent("~/scripts/myjavascript.js") %>"></script>

Bello anche l'approccio!
Federico Navarrete

0

Sulla base della risposta sopra ho scritto una piccola classe di estensione per lavorare con i file CSS e JS:

public static class TimestampedContentExtensions
{
    public static string VersionedContent(this UrlHelper helper, string contentPath)
    {
        var context = helper.RequestContext.HttpContext;

        if (context.Cache[contentPath] == null)
        {
            var physicalPath = context.Server.MapPath(contentPath);
            var version = @"v=" + new FileInfo(physicalPath).LastWriteTime.ToString(@"yyyyMMddHHmmss");

            var translatedContentPath = helper.Content(contentPath);

            var versionedContentPath =
                contentPath.Contains(@"?")
                    ? translatedContentPath + @"&" + version
                    : translatedContentPath + @"?" + version;

            context.Cache.Add(physicalPath, version, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero,
                CacheItemPriority.Normal, null);

            context.Cache[contentPath] = versionedContentPath;
            return versionedContentPath;
        }
        else
        {
            return context.Cache[contentPath] as string;
        }
    }
}

Invece di scrivere qualcosa come:

<link href="@Url.Content(@"~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content(@"~/Scripts/bootstrap.min.js")"></script>

Ora puoi scrivere:

<link href="@Url.VersionedContent(@"~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.VersionedContent(@"~/Scripts/bootstrap.min.js")"></script>

Vale a dire semplicemente sostituire Url.Contentcon Url.VersionedContent.

Gli URL generati hanno un aspetto simile a:

<link href="/Content/bootstrap.min.css?v=20151104105858" rel="stylesheet" type="text/css" />
<script src="/Scripts/bootstrap.min.js?v=20151029213517"></script>

Se utilizzi la classe di estensione, potresti voler aggiungere la gestione degli errori nel caso in cui la MapPathchiamata non funzioni, poiché contentPathnon è un file fisico.


0

Uso un modo simile per fare lo stesso che stai facendo senza modificare ogni pagina. Aggiunto un evento PreRender come file master. Mantiene la mia logica in un unico posto ed è applicabile sia ai file js che css.

protected void Page_PreRender(object sender, EventArgs e)
    {
        HtmlLink link = null;
        LiteralControl script = null;


        foreach (Control c in Header.Controls)
        {
            //StyleSheet add version
            if (c is HtmlLink)
            {
                link = c as HtmlLink;


                if (link.Href.EndsWith(".css", StringComparison.InvariantCultureIgnoreCase))
                {
                    link.Href += string.Format("?v={0}", ConfigurationManager.AppSettings["agVersion"]);
                }

            }

            //Js add version
            if (c is LiteralControl)
            {
                script = c as LiteralControl;

                if (script.Text.Contains(".js"))
                {
                    var foundIndexes = new List<int>();


                    for (int i = script.Text.IndexOf(".js\""); i > -1; i = script.Text.IndexOf(".js\"", i + 1))
                    {

                        foundIndexes.Add(i);
                    }

                    for (int i = foundIndexes.Count - 1; i >= 0; i--)
                    {

                        script.Text = script.Text.Insert(foundIndexes[i] + 3, string.Format("?v={0}", ConfigurationManager.AppSettings["agVersion"]));
                    }
                }

            }

        }
    }

0

È possibile sostituire la proprietà DefaultTagFormat di Scripts o Styles.

Scripts.DefaultTagFormat = @"<script src=""{0}?v=" + ConfigurationManager.AppSettings["pubversion"] + @"""></script>";
Styles.DefaultTagFormat = @"<link href=""{0}?v=" + ConfigurationManager.AppSettings["pubversion"] + @""" rel=""stylesheet""/>";

0

Per risolvere questo problema nella mia applicazione ASP.Net Ajax, ho creato un'estensione e poi ho chiamato nella pagina master.

Per maggiori dettagli, puoi passare attraverso il link .


0

Un modo semplice e intelligente per implementare il controllo delle versioni CSS nell'applicazione .net secondo il concetto di seguito .. non è necessario scrivere codice back-end.

<link href="<%="../../App_Themes/Base/css/main.css?v="+ DateTime.Now.ToString("yyyyMMddhhmmss") +""%>" rel="stylesheet" />

questo forzerà il download in ogni pagina di rendering, anche se i file non sono cambiati affatto.
Thanasis Ioannidis,

@ThanasisIoannidis Può usare dove i file vengono modificati regolarmente. un'altra opzione è aggiungere la chiave appVersion in web.config e usarla con il nome del file .. ma è necessario aggiornare quando si rilascia l'applicazione per prod.
SantoshK

-1

Il problema principale di farlo in questo modo è principalmente che dovrai ricordarti di aggiornare il tuo numero di versione nel codice ogni volta che apporti qualsiasi modifica ai tuoi file css o js.

Un modo forse migliore per farlo è impostare un parametro univoco garantito con ciascuno dei tuoi file css o js, ​​in questo modo:

<script src="scripts/myjavascript.js?_=<%=DateTime.Now.Ticks%>" type="text/javascript"></script>
<link href="styles/mystyle.css?_=<%=DateTime.Now.Ticks%>" rel="stylesheet" type="text/css" />

Ciò forza la richiesta dei file dal server ogni volta, il che significa anche che il tuo sito non sarà così performante al caricamento della pagina, poiché quei file non verranno mai memorizzati nella cache e utilizzeranno ogni volta la larghezza di banda non necessaria.

In sostanza, se ti ricordi di aggiornare il numero di versione ogni volta che viene apportata una modifica, puoi cavartela con il modo in cui lo stai facendo.


9
e utilizza anche abbondanti quantità di larghezza di banda.
Darren Kopp

2
Bene, non vuoi una nuova versione del JS ad ogni caricamento della pagina ... vuoi solo che il browser cerchi una nuova versione ogni volta che hai effettivamente una versione aggiornata.
kingdango

Questo è perfettamente accettabile per una soluzione temporanea su un file CSS da 50 KB durante lo sviluppo. +1
Colbs

-2

Per le pagine ASP.NET sto usando quanto segue

PRIMA

<script src="/Scripts/pages/common.js" type="text/javascript"></script>

DOPO (ricarica forzata)

 <script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>

L'aggiunta di DateTime.Now.Ticks funziona molto bene.


sì, il problema è con la larghezza di banda - come nei commenti sopra stackoverflow.com/a/2185918/59508
kiev
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.