memaksa browser untuk mendapatkan file js dan css terbaru di aplikasi asp.net

104

Beberapa browser menyimpan file js dan css, gagal menyegarkannya kecuali Anda memaksanya. Apa cara termudah.

Saya baru saja menerapkan solusi ini yang tampaknya berhasil.

Deklarasikan variabel versi di halaman Anda

  public string version { get; set; }

Dapatkan nomor versi dari kunci web.config

 version = ConfigurationManager.AppSettings["versionNumber"];

Di halaman aspx Anda, lakukan panggilan ke javascript dan stylesheet seperti itu

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

Jadi jika Anda menyetel versi = 1.1 dari 1.0 di web.config Anda, browser Anda akan mengunduh file terbaru yang diharapkan akan menyelamatkan Anda dan pengguna Anda dari beberapa frustrasi.

Apakah ada solusi lain yang berfungsi lebih baik, atau apakah ini akan menyebabkan masalah tak terduga untuk situs web?

kiev
sumber
Pertanyaan menarik, saya mengalami masalah yang sama baru-baru ini, tetapi hanya menjadi masalah selama pengujian pengembangan. Tidak terlalu peduli tentang hal itu karena kami tidak bermaksud untuk mengubah file tersebut setelah peluncuran. Akan sangat senang mengetahui solusi untuk referensi di masa mendatang!
Brett Allen
Satu-satunya masalah yang dapat saya lihat adalah bahwa perubahan pada web.config akan, di latar belakang, memanggil aplikasi restart: msdn.microsoft.com/en-us/library/aa478432.aspx
monty
Terima kasih atas pertanyaannya Ini membantu saya dalam memecahkan masalah besar.
Reddy

Jawaban:

76

Saya menyelesaikan ini dengan memasang stempel waktu terakhir yang dimodifikasi sebagai parameter kueri ke skrip.

Saya melakukan ini dengan metode ekstensi, dan menggunakannya dalam file CSHTML saya. Catatan: implementasi ini meng-cache stempel waktu selama 1 menit sehingga kami tidak terlalu banyak membuang-buang disk.

Berikut adalah metode ekstensi:

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

Lalu di halaman CSHTML:

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

Dalam HTML yang dirender, ini muncul sebagai:

 <script type='text/javascript' src='/MyJavascriptFile.js?20111129120000'></script>
Adam Tegen
sumber
1
ini bagus untuk mvc, saya ingin tahu apakah kerangka kerja mvc 5 terbaru menangani masalah ini? Pendekatan yang digunakan bundling dengan - {version} wildcard juga merupakan cara untuk mengatasi masalah ini, namun ini membutuhkan file untuk diganti namanya setelah setiap build baru ...
kiev
Saya menggunakan dasar-dasar contoh MVC Anda di situs web formulir, dan ini berfungsi dengan baik, jadi terima kasih telah berbagi!
Bryan
Haruskah ada alasan untuk khawatir tentang menampilkan cap tanggal / waktu yang terakhir diubah untuk file sumber daya? Jika file yang digunakan memiliki cap tanggal / waktu beberapa tahun yang lalu, mungkinkah informasi yang perusahaan mungkin tidak ingin publikasikan kepada penggunanya?
Bryan
Ini adalah cara standar, sebagian besar aplikasi mengikuti. Tetapi stempel waktu itu harus berubah hanya ketika Anda menerapkan atau membangun aplikasi Anda. Sebaliknya setiap kali pengguna menyegarkan halaman atau beralih ke halaman lain di aplikasi Anda. Browser akan mengunduh semua stylesheet dan javascript Anda lagi, yang tidak baik
Tarun
2
Apa dampaknya pada kinerja halaman? Berapa lama penundaan yang dapat ditimbulkan untuk memuat halaman?
Durgesh Sonawane
28

Solusi Anda berhasil. Ini sebenarnya cukup populer.

Even Stack Overflow menggunakan metode serupa:

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

Di mana v=6184mungkin nomor revisi SVN.

Daniel Vassallo
sumber
Ini akan menjadi pendekatan yang jauh lebih membebani daripada yang dijelaskan dalam jawaban yang diterima. Memeriksa versi SVN file setiap kali halaman disajikan merupakan overhead performa, terutama karena jumlah pengguna meningkat dari waktu ke waktu.
Neolisk
4
Anda bisa mendapatkan nomor revisi selama pembuatan, menuliskannya ke dalam file (misalnya, sebagian file .cs), menyertakan file itu dalam proyek Anda, jadi Anda tidak perlu membacanya dari svn saat runtime. Saya telah menggunakan pendekatan ini dengan msbuild untuk meletakkan nomor revisi di file AssemblyInfo.cs saya dari svn.
Ramazan Binarbasi
2
Menggunakan nomor versi / revisi global memiliki setidaknya satu kelemahan: menerbitkan pembaruan situs web membuat cache browser tidak valid untuk semua file .js dan .css, bukan hanya file yang berubah. Ini mungkin tidak menjadi masalah di sebagian besar aplikasi, tetapi saya menyebutkannya untuk kelengkapan.
Adam Tegen
Jika Anda memperbarui versi file assemblyinfo.cs Anda secara otomatis selama penyebaran atau build, versi minor dapat digunakan untuk nomor itu.
kristianp
28

Di ASP.NET Core (MVC 6) ini berfungsi di luar kotak melalui 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" />
metalheart
sumber
1
Terima kasih telah memberi tahu kami! Saya tidak tahu sebelumnya!
Federico Navarrete
18

ASP.NET MVC akan menangani ini untuk Anda jika Anda menggunakan bundel untuk JS / CSS Anda. Ini akan secara otomatis menambahkan nomor versi dalam bentuk GUID ke bundel Anda dan hanya memperbarui GUID ini ketika bundel diperbarui (alias salah satu file sumber memiliki perubahan).

Ini juga membantu jika Anda memiliki banyak file JS / CSS karena dapat sangat meningkatkan waktu muat konten!

Lihat disini

jonesy827
sumber
Apakah maksud Anda jika kita menggunakan bundel dalam aplikasi MVC, tidak perlu metode apa pun dalam jawaban yang diposting di sini? Jika demikian, membundel jauh lebih penting yang pernah saya pikirkan. Bisakah Anda menjelaskan kepada kami tentang masalah ini? Terima kasih.
Jack
1
Ya persis. Selama skrip Anda disertakan dalam satu bundel, itu akan menghasilkan nomor versi secara otomatis untuk setiap bundel ketika perubahan terdeteksi di salah satu file sumber bundel.
jonesy827
Dan jangan lupa bahwa Anda masih sakit kepala sebagai pengembang. Bundling ASP.NET membantu sekarang selama debugging dan pengembangan.
it3xl
12

Ada cara built-in di asp.net untuk ini: bundling . Gunakan saja. Setiap versi baru akan memiliki akhiran unik "? V = XXXXXXX". Dalam mode debug, bundling tidak aktif, untuk mengaktifkan pengaturan make di web.config:

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

Atau tambahkan ke metode RegisterBundles (bundle BundleCollection):

BundleTable.EnableOptimizations = true;

Sebagai contoh:

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")
Alex Tkachuk
sumber
Tapi ini hanya akan bekerja di lingkungan rilis atau produksi. Bagaimana dengan pengembangan saat mode debug aktif? Apakah bundle masih memperbaiki masalah ini?
VAAA
Ya, bundlind tidak membuat hidup developer lebih mudah. Anda harus menekan Ctrl-F5 setelah setiap perubahan skrip. Dan jika Anda memiliki bingkai, itu akan menjadi lebih lucu.
it3xl
6

Ada jawaban yang lebih sederhana untuk ini daripada jawaban yang diberikan oleh op dalam pertanyaan (pendekatannya sama):

Tentukan kunci di web.config:

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

Lakukan panggilan ke pengaturan aplikasi langsung dari halaman aspx:

<link href="styles/navigation.css?v=<%=ConfigurationManager.AppSettings["VersionNumber"]%>" rel="stylesheet" type="text/css" />
JackArbiter
sumber
Saya suka ini, tetapi saya prihatin mengapa solusi ini memiliki suara yang sangat sedikit ...
SimplyInk
@SimplyInk Saya tidak tahu, tapi ada 20 jawaban berbeda, jadi itu mungkin ada hubungannya dengan itu. Jika berhasil dan Anda menyukainya, silakan beri suara positif.
JackArbiter
4

Berdasarkan jawaban Adam Tegan , dimodifikasi untuk digunakan dalam aplikasi formulir web.

Dalam kode kelas .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);
    }
}

Di markup aspx:

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

Dan di HTML yang dirender, itu muncul sebagai

<script type="text/javascript" src='/js/exampleJavaScriptFile.js?v=20150402021544'></script>
Bryan
sumber
2
Hei! Contoh Anda berfungsi, tetapi Anda harus menghapus referensi caching atau memperbaiki kode untuk menggunakan cache karena dapat membingungkan mengapa Anda menggunakannya. Untuk menggunakan cache, Anda harus menambahkan versi file ke cache menggunakan metode context.Cache.Add dalam konteks kasus.Cache [nama file] == null. Jika konteks.Cache [nama file]! = Null maka Anda harus mengembalikan nilai yang di-cache (konteks.Cache [nama file])
Flavia Obreja
1
Flavia, menurut saya penjelasan Anda masuk akal, dan menurut saya ini adalah implementasi yang lebih sederhana dan lebih efisien. Terima kasih telah memposting komentar dan umpan balik yang bermanfaat.
Bryan
4

Menariknya, situs ini memiliki masalah dengan pendekatan yang Anda jelaskan sehubungan dengan beberapa penyiapan proxy, meskipun seharusnya aman.

Periksa diskusi Meta Stack Overflow ini .

Jadi mengingat itu, mungkin masuk akal untuk tidak menggunakan parameter GET untuk memperbarui, tetapi nama file yang sebenarnya:

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

meskipun ini lebih banyak pekerjaan yang harus dilakukan, karena Anda harus benar-benar membuat file, atau membuat ulang URL untuk itu.

Pekka 웃
sumber
4

Saya ingin satu liner sederhana untuk membuat jalur unik untuk merusak cache. Ini berhasil untuk saya:

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

Jika file telah dimodifikasi sejak terakhir kali dimuat di halaman, browser akan menarik file yang diperbarui.

Ini menghasilkan last modifiedcap dari .jsfile dan membuangnya di sana alih-alih versi yang mungkin tidak mudah untuk mendapatkan akses.

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

Pilihan lain adalah mendapatkan checksum dari file tersebut.

penembak jitu
sumber
1
Sejauh ini cara termudah untuk melakukan ini, dan mungkin biaya overhead terendah.
Tony Hinkle
1
Solusi yang tepat. Saya juga menguji Chrome 70, Firefox 63 dan IE 11 untuk memastikan bahwa caching benar-benar berfungsi. Ini. Ini hanya merusak cache pada versi baru dari file tersebut, setidaknya pada versi terbaru dari browser. Saya pernah mendengar disebutkan di tempat lain bahwa beberapa browser memuat ulang setiap file dengan querystring (?). Mungkin dulu masalahnya atau mungkin masih berlaku dengan Safari dan Opera. DK.
Brad Mathews
3

Berikut adalah pendekatan yang berfungsi dengan ASP.NET 5 / MVC 6 / vNext .

Langkah 1: Buat kelas untuk mengembalikan waktu tulis terakhir file, mirip dengan jawaban lain di utas ini. Catatan, ini memerlukan injeksi ketergantungan ASP.NET 5 (atau lainnya).

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

Langkah 2: Daftarkan layanan yang akan diinjeksi di dalam startup.cs :

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

Langkah 3: Kemudian, di ASP.NET 5, dimungkinkan untuk menyuntikkan layanan langsung ke tampilan tata letak seperti _Layout.cshtml seperti ini:

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

Ada beberapa sentuhan akhir yang dapat dilakukan untuk menggabungkan jalur fisik dengan lebih baik dan menangani nama file dalam gaya yang lebih konsisten dengan sintaks, tetapi ini adalah titik awal. Semoga membantu orang-orang pindah ke ASP.NET 5.

Ender2050
sumber
perilaku ini sebenarnya didukung di luar kotak, lihat jawaban saya
metalheart
3

Saya telah menggunakan teknik yang sedikit berbeda di situs aspnet MVC 4 saya:

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

Kemudian dalam tampilan sebenarnya:

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

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

Ini berfungsi untuk saya di semua browser. Di sini saya telah menggunakan PHP untuk menghasilkan no acak. Anda dapat menggunakan bahasa sisi server Anda sendiri.`

Mukesh Rai
sumber
Jawaban yang bagus, tetapi ASP MVC bisa menjadi sedikit bermasalah jika Anda tidak mempertimbangkan apa yang dijelaskan Adam karena saya mencobanya dan folder Bundle tidak mengenalinya jika Anda bekerja dengan MVC 5. Tapi terima kasih atas sarannya!
Federico Navarrete
2

Mulai dari jawaban di atas saya memodifikasi sedikit kode agar helper bekerja dengan file CSS juga dan menambahkan versi setiap kali Anda melakukan beberapa perubahan pada file dan tidak hanya ketika Anda melakukan build

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;
        }
    }
}
Sergi Mulà
sumber
1

Dapatkan waktu modifikasi file, seperti yang ditunjukkan di bawah ini

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

Tambahkan ini dengan masukan sebagai string kueri

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

Sebut ini dari markup.

Pendekatan Pembantu Ekstensi MVC

Tambahkan metode ekstensi

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

    }
}

Tambahkan namespace ini di 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>

Gunakan dalam tampilan sebagai

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

Saran sebelumnya yang disederhanakan dan pemberian kode untuk pengembang Formulir Web .NET.

Ini akan menerima url relatif ("~ /") dan absolut di jalur file ke sumber daya.

Masukkan file kelas ekstensi statis, berikut ini:

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

Dan kemudian menyebutnya di Halaman Master Anda seperti itu:

<link type="text/css" rel="stylesheet" href="<%= Context.VersionedContent("~/styles/mystyle.css") %>" />
<script type="text/javascript" src="<%= Context.VersionedContent("~/scripts/myjavascript.js") %>"></script>
Jason Ellingson
sumber
Pendekatan yang bagus juga!
Federico Navarrete
0

Berdasarkan jawaban di atas, saya telah menulis kelas ekstensi kecil untuk bekerja dengan file CSS dan 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;
        }
    }
}

Dari pada menulis sesuatu seperti:

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

Anda sekarang dapat menulis:

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

Yaitu cukup ganti Url.Contentdengan Url.VersionedContent.

URL yang dihasilkan terlihat seperti ini:

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

Jika Anda menggunakan kelas ekstensi, Anda mungkin ingin menambahkan penanganan kesalahan jika MapPathpanggilan tidak berfungsi, karena contentPathbukan file fisik.

Uwe Keim
sumber
0

Saya menggunakan cara serupa untuk melakukan hal yang sama yang Anda lakukan tanpa mengubah setiap halaman. Menambahkan acara PreRender adalah file master. Itu membuat logika saya di satu tempat dan berlaku untuk file js dan 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"]));
                    }
                }

            }

        }
    }
Jay
sumber
0

Anda bisa mengganti properti DefaultTagFormat dari Scripts atau Styles.

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

Untuk mengatasi masalah ini di aplikasi ASP.Net Ajax saya, saya membuat ekstensi dan kemudian memanggil di halaman master.

Untuk lebih jelasnya bisa melalui link .

Kasim Husaini
sumber
0

Cara mudah dan cerdas untuk mengimplementasikan versi css pada aplikasi .net dengan konsep di bawah ini .. tidak perlu menulis kode back-end.

<link href="<%="../../App_Themes/Base/css/main.css?v="+ DateTime.Now.ToString("yyyyMMddhhmmss") +""%>" rel="stylesheet" />
SantoshK
sumber
ini akan memaksa unduhan di setiap perenderan halaman, meskipun file tidak berubah sama sekali.
Thanasis Ioannidis
@ThanasisIoannidis Dapat digunakan di mana file diubah secara teratur. Pilihan lainnya adalah menambahkan kunci appVersion di web.config dan gunakan dengan nama file .. tetapi Anda perlu memperbarui ketika Anda merilis aplikasi untuk prod.
SantoshK
-1

Masalah utama dengan melakukannya dengan cara ini terutama adalah Anda harus ingat untuk memperbarui nomor versi Anda dalam kode Anda setiap kali Anda membuat perubahan pada file css atau js Anda.

Cara yang mungkin lebih baik untuk melakukannya adalah dengan menetapkan parameter unik yang dijamin dengan setiap file css atau js Anda, seperti:

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

Ini memaksa file untuk diminta dari server setiap saat, yang juga berarti bahwa situs Anda tidak akan berkinerja sebaik saat pemuatan halaman, karena file tersebut tidak akan pernah disimpan dalam cache, dan akan menggunakan bandwidth yang tidak diperlukan setiap saat.

Pada dasarnya, jika Anda ingat untuk memperbarui nomor versi setiap kali ada perubahan, Anda dapat memahami cara melakukannya.

Tim S. Van Haren
sumber
9
dan juga menggunakan bandwidth dalam jumlah besar.
Darren Kopp
2
Benar, Anda tidak ingin versi baru JS pada setiap pemuatan halaman ... Anda hanya ingin browser mencari versi baru setiap kali Anda benar-benar memiliki versi yang diperbarui.
kingdango
Ini sangat dapat diterima untuk solusi temp pada file css 50KB saat dalam pengembangan. +1
Colbs
-2

Untuk halaman ASP.NET saya menggunakan berikut ini

SEBELUM

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

SETELAH (isi ulang paksa)

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

Menambahkan DateTime.Now.Ticks bekerja dengan sangat baik.

Ravi Ram
sumber
ya, masalahnya ada pada bandwidth - seperti di komentar di atas stackoverflow.com/a/2185918/59508
kiev