tarayıcıları asp.net uygulamasındaki en son js ve css dosyalarını almaya zorlar


104

Bazı tarayıcılar js ve css dosyalarını önbelleğe alır ve siz onları zorlamadıkça yenilemez. En kolay yol nedir.

İşe yarayan bu çözümü yeni uyguladım.

Sayfanızda bir sürüm değişkeni bildirin

  public string version { get; set; }

Web.config anahtarından sürüm numarasını alın

 version = ConfigurationManager.AppSettings["versionNumber"];

Aspx sayfanızda javascript ve stil sayfalarına bu şekilde çağrı yapın

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

Dolayısıyla, web.config dosyanızda version = 1.1'i 1.0'dan ayarlarsanız, tarayıcınız en son dosyaları indirecek ve bu da sizi ve kullanıcılarınızı biraz hayal kırıklığına uğratacaktır.

Daha iyi çalışan başka bir çözüm var mı yoksa bu bir web sitesi için öngörülemeyen sorunlara neden olur mu?


İlginç soru, son zamanlarda aynı sorunu yaşadım, ancak yalnızca geliştirme testi sırasında bir sorundu. Bu dosyayı lansmandan sonra değiştirmeyi düşünmediğimiz için pek umursamadık. Gelecekte başvurmak için bir çözüm bilmek isterim!
Brett Allen

: Sadece görebildiğim sorunu web.config değişiklikler, arka planda bir uygulama yeniden başlatma arayacak olmasıdır msdn.microsoft.com/en-us/library/aa478432.aspx
monty

Soru için teşekkür ederim. Bu, büyük bir sorunu çözmeme yardımcı oldu.
Reddy

Yanıtlar:


76

Bunu, komut dosyalarına sorgu parametresi olarak son değiştirilen zaman damgasını yapıştırarak çözdüm.

Bunu bir uzantı yöntemiyle ve bunu CSHTML dosyalarımda kullanarak yaptım. Not: Bu uygulama, zaman damgasını 1 dakika boyunca önbelleğe alır, bu nedenle diski çok fazla atmayız.

İşte uzatma yöntemi:

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;
        }
    }
}

Ve sonra CSHTML sayfasında:

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

Oluşturulan HTML'de şu şekilde görünür:

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

1
bu mvc için harika, acaba en son mvc 5 çerçevesi bu sorunu çözüyor mu? Paketlemenin - {version} joker karakteriyle kullandığı yaklaşım da bu sorunu çözmenin bir yoludur, ancak her yeni derlemeden sonra dosyaların yeniden adlandırılmasını gerektirir ...
kiev

MVC örneğinizin temellerini bir web formları web sitesinde kullanıyorum ve harika çalışıyor, paylaştığınız için teşekkür ederiz!
Bryan

Kaynak dosyalar için son değiştirilen tarih / saat damgasını görüntülemekten endişe duymanız için herhangi bir neden var mı? Kullanılan bir dosyanın birkaç yıl geçmiş bir tarih / saat damgası varsa, bir şirketin kullanıcılarına açık olmasını istemeyebileceği bilgisi olabilir mi?
Bryan

Bu standart yoldur, çoğunlukla uygulamalar izler. Ancak bu zaman damgası yalnızca uygulamanızı dağıtırken veya oluşturduğunuzda değişmelidir. Aksi takdirde, kullanıcı her sayfayı yenilediğinde veya uygulamanızda başka sayfalara geçiş yaptığında. Tarayıcı, tüm stil sayfalarınızı ve javascript'i tekrar indirecek, bu iyi değil
Tarun

2
Sayfanın performansı üzerindeki etkisi nedir? Sayfanın yüklenmesi ne kadar gecikmeye neden olabilir?
Durgesh Sonawane

28

Çözümünüz işe yarıyor. Aslında oldukça popüler.

Stack Overflow bile benzer bir yöntem kullanır:

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

v=6184Muhtemelen SVN revizyon numarası nerede .


Bu, kabul edilen cevapta tarif edilenden çok daha fazla vergilendirici bir yaklaşım olacaktır. Bir sayfa her sunulduğunda dosyanın SVN sürümünün kontrol edilmesi, özellikle kullanıcı sayısı zamanla arttığı için bir performans yüküdür.
Neolisk

4
Derleme sırasında revizyon numarasını alabilir, bir dosyaya yazabilir (örn. Kısmi .cs dosyası), bu dosyayı projenize dahil edebilirsiniz, böylece çalışma zamanında svn'den okumanıza gerek kalmaz. Bu yaklaşımı msbuild ile revizyon numaralarını svn'den AssemblyInfo.cs dosyalarıma koymak için kullandım.
Ramazan Binarbasi

2
Genel bir sürüm / revizyon numarası kullanmanın en az bir dezavantajı vardır: bir web sitesi güncellemesi yayınlamak, yalnızca değişen dosyalar değil, tüm .js ve .css dosyaları için tarayıcı önbelleklerini geçersiz kılar. Bu muhtemelen başvuruların çoğunda önemli değildir, ancak eksiksizlik için bundan bahsediyorum.
Adam Tegen

Bir dağıtım veya derleme sırasında assemblyinfo.cs dosyalarınızın sürümünü otomatik olarak güncellerseniz, bu numara için ikincil sürüm kullanılabilir.
kristianp

28

In ASP.NET Çekirdek (MVC 6) Bu aracılığıyla kutunun çalışır asp-append-versionetiketi yardımcı:

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

1
Bize bildirdiğiniz için teşekkür ederiz! Bunu daha önce bilmiyordum!
Federico Navarrete

18

JS / CSS'niz için paketler kullanıyorsanız ASP.NET MVC bunu sizin için halleder. Paketlerinize GUID biçiminde bir sürüm numarasını otomatik olarak ekler ve yalnızca paket güncellendiğinde bu GUID'yi günceller (diğer bir deyişle kaynak dosyalardan herhangi birinde değişiklik olduğunda).

Bu, içerik yükleme sürelerini büyük ölçüde iyileştirebileceğinden, bir ton JS / CSS dosyanız varsa da yardımcı olur!

Buraya Bakın


Bir MVC uygulamasında paket kullanırsak, burada yayınlanan yanıtta hiçbir yöntem gerekmediğini mi söylüyorsunuz? Eğer öyleyse, paketlemek gerçekten düşündüğümden çok daha önemli. Bize bu konu hakkında açıklık getirir misiniz? Teşekkürler.
Jack

1
Evet kesinlikle. Komut dosyalarınız bir pakete dahil olduğu sürece, paketin kaynak dosyalarından herhangi birinde değişiklikler tespit edildiğinde her paket için otomatik olarak bir sürüm numarası oluşturacaktır.
jonesy827

Ve bir geliştirici olarak hala baş ağrınız olduğunu unutmayın. ASP.NET paketlemesi, hata ayıklama ve geliştirme sırasında nohow yardımcı olur.
it3xl

12

Bunun için asp.net'te yerleşik bir yol vardır: bundling . Sadece kullan. Her yeni sürümün benzersiz "? V = XXXXXXX" soneki olacaktır. Hata ayıklama modunda paketleme, web.config dosyasındaki yap ayarını açmak için kapalıdır:

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

Veya RegisterBundles (BundleCollection paketleri) yöntemine ekleyin:

BundleTable.EnableOptimizations = true;

Örneğin:

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")

Ancak bu yalnızca yayın veya üretim ortamlarında çalışacaktır. Hata ayıklama modu açıkken geliştirme ne olacak? Paket hala bu sorunu çözüyor mu?
VAAA

Evet, bundlind geliştiricilerin daha kolay yaşamasını sağlamaz. Her komut dosyası değişikliğinden sonra Ctrl-F5 tuşlarına basmanız gerekir. Ve eğer çerçeveleriniz varsa, daha da eğlenceli olacak.
it3xl

7

Sorudaki op tarafından verilen cevaptan daha basit bir cevap var (yaklaşım aynıdır):

Anahtarı web.config dosyasında tanımlayın:

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

Doğrudan aspx sayfasından uygulama ayarlarına çağrı yapın:

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

Bunu beğendim, ancak bu çözümün neden bu kadar az oy
aldığını merak

@SimplyInk Bilmiyorum ama 20 farklı cevap var, bu yüzden bununla bir ilgisi olabilir. Çalışırsa ve beğenirseniz, ona olumlu oy vermekten çekinmeyin.
JackArbiter

4

Dayanarak Adam Tegan cevabı , bir web formları uygulamasında kullanılmak üzere modifiye.

.Cs sınıf kodunda:

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);
    }
}

Aspx işaretlemesinde:

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

Oluşturulan HTML'de şu şekilde görünür:

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

2
Hey! Örneğiniz çalışıyor, ancak önbelleği kullanmak için önbelleğe alma referanslarını kaldırmanız veya kodu düzeltmeniz gerekir, çünkü onu neden kullandığınız kafa karıştırıcı olabilir. Önbelleği kullanmak için, durumda context.Cache [dosyaadı] == null içinde context.Cache.Add yöntemini kullanarak dosyanın sürümünü önbelleğe eklemelisiniz. Eğer context.Cache [dosyaadı]! = Null ise, önbelleğe alınan değeri (context.Cache [dosyaadı]) döndürmelisiniz
Flavia Obreja

1
Flavia, açıklamanızın mantıklı olduğunu düşünüyorum ve bence daha basit, daha verimli bir uygulama. Faydalı yorumları ve geri bildirimleri gönderdiğiniz için teşekkür ederiz.
Bryan

4

İlginç bir şekilde, bu sitenin bazı proxy kurulumlarıyla bağlantılı olarak tanımladığınız yaklaşımla ilgili sorunları var, ancak hata korumalı olması gerekir.

Bu Meta Yığın Taşması tartışmasına göz atın .

Dolayısıyla, bunun ışığında, güncellemek için bir GET parametresi değil, gerçek dosya adını kullanmak mantıklı olabilir:

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

Bu yapılacak daha fazla iş olsa da, dosyayı gerçekten oluşturmanız veya bunun için bir URL yeniden yazmanız gerekeceği için.


4

Önbelleği bozmak için yolu benzersiz kılmak için basit bir tek astar istedim. Bu benim için çalıştı:

<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>

Dosya sayfaya en son yüklendiğinden beri değiştirildiyse, tarayıcı güncellenen dosyayı çekecektir.

Bu üretir last modifiedgelen damgası .jsyerine erişebilmek için kolay olmayabilir versiyonunun orada dosya ve aynalar.

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

Diğer bir seçenek de dosyanın sağlama toplamını almak olabilir.


1
Bunu yapmanın açık ara en kolay yolu ve muhtemelen en düşük genel gider.
Tony Hinkle

1
Mükemmel çözüm. Önbelleğe almanın gerçekten çalıştığından emin olmak için Chrome 70, Firefox 63 ve IE 11'i de test ettim. Bu. Bu, yalnızca dosyanın yeni sürümlerinde, en azından tarayıcıların en son sürümlerinde önbelleğe almayı bozar. Başka bir yerde bazı tarayıcıların her dosyayı bir sorgu dizesiyle (?) Yeniden yüklediğinden bahsettiğini duydum. Belki eskiden durum böyleydi veya belki Safari ve Opera için hala geçerlidir. DK.
Brad Mathews

3

İşte ASP.NET 5 / MVC 6 / vNext ile çalışan bir yaklaşım .

Adım 1: Bu ileti dizisindeki diğer yanıtlara benzer şekilde, dosyanın son yazma zamanını döndürmek için bir sınıf oluşturun. Not, bu ASP.NET 5 (veya başka) bağımlılık enjeksiyonu gerektirir.

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;
     }
}

Adım 2: startup.cs içine enjekte edilecek hizmeti kaydedin :

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

Adım 3: Ardından, ASP.NET 5'te, hizmeti doğrudan _Layout.cshtml gibi bir düzen görünümüne şu şekilde enjekte etmek mümkündür :

@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>

Fiziksel yolları daha iyi birleştirmek ve dosya adını sözdizimi ile daha tutarlı bir tarzda ele almak için yapılabilecek bazı son rötuşlar vardır, ancak bu bir başlangıç ​​noktasıdır. Umarım insanların ASP.NET 5'e geçmesine yardımcı olur.


Bu davranış aslında kutudan çıktığı desteklenir, bkz benim cevap
Metalheart

3

Aspnet MVC 4 sitemde biraz farklı bir teknik kullandım:

_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;
    }
}

Sonra gerçek görünümlerde:

 @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>

Bu benim için tüm tarayıcılarda çalışıyor. Burada PHP'yi rasgele hayır üretmek için kullandım. Kendi sunucu tarafı dilinizi kullanabilirsiniz.`


Güzel cevap, ancak Adam'ın açıkladığı şeyi düşünmezseniz ASP MVC biraz sorunlu olabilir çünkü ben denedim ve MVC 5 ile çalışıyorsanız Bundle klasörü bunu tanımıyor. Ancak öneri için teşekkürler!
Federico Navarrete

2

Yukarıdaki cevaptan başlayarak , yardımcının CSS dosyalarıyla da çalışmasını sağlamak için kodu biraz değiştirdim ve sadece derlemeyi yaptığınızda değil, dosyalarda bazı değişiklikler yaptığınızda her seferinde bir sürüm ekledim.

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

Aşağıda gösterildiği gibi dosya değiştirme zamanını alın

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

Bunu sorgu dizesi olarak girdi ile ekleyin

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

Bunu işaretlemeden arayın.

MVC Uzatma Yardımcısı Yaklaşımı

Bir uzantı yöntemi ekleyin

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());
      }

    }
}

Bu ad alanını web.config dosyasına ekleyin

<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>

Görünümünde kullanın

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

1

Basitleştirilmiş önceki öneriler ve .NET Web Formları geliştiricileri için kod sağlama.

Bu, kaynağa giden dosya yolundaki hem göreli ("~ /") hem de mutlak url'leri kabul eder.

Aşağıdakileri bir statik uzantılar sınıf dosyası koyun:

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];
}

Ve sonra Ana Sayfanızda şu şekilde çağırın:

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

Çok güzel bir yaklaşım!
Federico Navarrete

0

Yukarıdaki cevaba dayanarak, CSS ve JS dosyalarıyla çalışmak için küçük bir uzantı sınıfı yazdım:

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;
        }
    }
}

Şunun gibi bir şey yazmak yerine:

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

Şimdi yazabilirsiniz:

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

Yani basitçe yerine Url.Contentsahip Url.VersionedContent.

Oluşturulan URL'ler şuna benzer:

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

Uzantı sınıfını kullanırsanız, fiziksel bir dosya olmadığı için MapPatharamanın çalışmaması durumunda hata işleme eklemek isteyebilirsiniz contentPath.


0

Her sayfayı değiştirmeden yaptığınız şeyi yapmak için benzer bir yol kullanıyorum. Bir PreRender etkinliği ana dosya eklendi. Mantığımı tek bir yerde tutar ve hem js hem de css dosyalarına uygulanabilir.

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

Komut Dosyalarının veya Stillerin DefaultTagFormat özelliğini geçersiz kılabilirsiniz.

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

0

ASP.Net Ajax uygulamamda bu sorunu çözmek için bir uzantı oluşturdum ve ardından ana sayfada çağırdım.

Daha fazla ayrıntı için bağlantı üzerinden gidebilirsiniz .


0

Aşağıdaki konsept ile .net uygulamasında css sürümlemeyi gerçekleştirmenin kolay ve akıllı yolu .. arka uç kodu yazmaya gerek yok.

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

bu, dosyalar hiç değişmemiş olsa bile, her sayfa oluşturmada indirmeye zorlar.
Thanasis İoannidis

@ThanasisIoannidis Dosyaların düzenli olarak değiştiği yerlerde kullanılabilir. başka bir seçenek de web.config dosyasında appVersion anahtarı eklemek ve dosya adıyla kullanmaktır .. ancak uygulamayı üretim için yayınladığınızda güncellemeniz gerekir.
SantoshK

-1

Bunu bu şekilde yapmanın temel sorunu, css veya js dosyalarınızda her değişiklik yaptığınızda kodunuzdaki sürüm numaranızı güncellemeyi hatırlamanız gerekmesidir.

Bunu yapmanın muhtemelen daha iyi bir yolu, css veya js dosyalarınızın her biri için garantili benzersiz bir parametre ayarlamaktır, örneğin:

<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" />

Bu, dosyaları her seferinde sunucudan istenmeye zorlar, bu aynı zamanda sitenizin sayfa yüklendikten sonra o kadar performanslı olmayacağı anlamına gelir, çünkü bu dosyalar hiçbir zaman önbelleğe alınmaz ve her seferinde gereksiz bant genişliği kullanır.

Esasen, her değişiklik yapıldığında sürüm numarasını güncellemeyi hatırlayabilirseniz, bunu nasıl yaptığınızdan kurtulabilirsiniz.


9
ve çok miktarda bant genişliği kullanır.
Darren Kopp

2
Doğru, her sayfa yüklemesinde JS'nin yeni bir sürümünü istemezsiniz ... sadece, gerçekten güncellenmiş bir sürüme sahip olduğunuz her seferde tarayıcının yeni bir sürüm aramasını istersiniz.
kingdango

Bu, geliştirme sırasında 50KB css dosyasında geçici bir çözüm için tamamen kabul edilebilir. +1
Colbs

-2

ASP.NET sayfaları için aşağıdakileri kullanıyorum

ÖNCE

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

SONRA (yeniden yüklemeye zorla)

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

DateTime.Now.Ticks eklemek çok iyi çalışıyor.


evet, sorun bant genişliğiyle ilgili - stackoverflow.com/a/2185918/59508
kiev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.