asp.net एप्लिकेशन में नवीनतम जेएस और सीएसएस फ़ाइलों को प्राप्त करने के लिए ब्राउज़रों को मजबूर करें


104

कुछ ब्राउज़र js और css फ़ाइलों को कैश करते हैं, जब तक कि आप उन्हें मजबूर न करें, उन्हें रिफ्रेश करने में विफल। सबसे आसान तरीका क्या है।

मैंने सिर्फ इस समाधान को लागू किया है जो काम करने लगता है।

अपने पृष्ठ पर एक संस्करण चर घोषित करें

  public string version { get; set; }

संस्करण संख्या web.config कुंजी से प्राप्त करें

 version = ConfigurationManager.AppSettings["versionNumber"];

अपने aspx पेज में जावास्क्रिप्ट और स्टाइलशीट को कॉल करें जैसे

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

इसलिए यदि आप अपने web.config में 1.0 से संस्करण = 1.1 सेट करते हैं तो आपका ब्राउज़र नवीनतम फ़ाइलों को डाउनलोड करेगा जो आपको और आपके उपयोगकर्ताओं को कुछ निराशा से बचाएगी।

क्या एक और समाधान है जो बेहतर काम करता है, या यह एक वेबसाइट के लिए किसी भी अप्रत्याशित मुद्दों का कारण होगा?


दिलचस्प सवाल, मेरा हाल ही में एक ही मुद्दा था, लेकिन विकास परीक्षण के दौरान केवल एक मुद्दा था। इसकी बहुत परवाह नहीं की क्योंकि हम लॉन्च के बाद उन फाइल को बदलने का इरादा नहीं रखते हैं। भविष्य के संदर्भ के लिए एक समाधान जानना पसंद करेंगे!
ब्रेट एलन

एकमात्र मुद्दा जो मैं देख सकता हूं, वह यह है कि पृष्ठभूमि में web.config वसीयत में परिवर्तन, एक आवेदन पुनः आरंभ करें: msdn.microsoft.com/en-us/library/aa478432.aspx
monty

सवाल के लिए आपका धन्यवाद। इससे मुझे एक बड़े मुद्दे को सुलझाने में मदद मिली।
रेड्डी

जवाबों:


76

मैंने स्क्रिप्ट के लिए क्वेरी पैरामीटर के रूप में एक अंतिम संशोधित टाइमस्टैम्प से निपटकर इसे हल किया।

मैंने एक एक्सटेंशन विधि के साथ, और अपनी CSHTML फ़ाइलों में इसका उपयोग किया। नोट: यह कार्यान्वयन 1 मिनट के लिए टाइमस्टैम्प को कैश करता है, इसलिए हम डिस्क को बहुत अधिक नहीं फेंकते हैं।

यहाँ विस्तार विधि है:

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

और फिर CSHTML पेज में:

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

प्रदान किए गए HTML में, यह इस प्रकार दिखाई देता है:

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

1
यह mvc के लिए बहुत अच्छा है, मुझे आश्चर्य है कि क्या नवीनतम mvc 5 फ्रेमवर्क इस मुद्दे को संभालता है? बंडलिंग जिस दृष्टिकोण के साथ उपयोग करता है - {संस्करण} वाइल्डकार्ड भी इस समस्या को हल करने का एक तरीका है, हालाँकि इसके लिए फ़ाइलों को प्रत्येक नए निर्माण के बाद नाम बदलने की आवश्यकता होती है ...
kiev

मैं एक वेबफॉर्म वेबसाइट में आपके एमवीसी उदाहरण के मूल का उपयोग कर रहा हूं, और यह बहुत अच्छा काम कर रहा है, इसलिए साझा करने के लिए धन्यवाद!
ब्रायन

क्या संसाधन फ़ाइलों के लिए अंतिम संशोधित तिथि / समय स्टाम्प प्रदर्शित करने के बारे में चिंतित होने का कोई कारण होना चाहिए? यदि किसी फ़ाइल का उपयोग किया जा रहा है, तो कुछ साल पहले की तारीख / समय की मोहर होती है, क्या यह जानकारी हो सकती है कि कोई कंपनी अपने उपयोगकर्ताओं के लिए सार्वजनिक नहीं होना चाहती है?
ब्रायन

यह मानक तरीका है, ज्यादातर एप्लिकेशन निम्नानुसार हैं। लेकिन उस समय स्टाम्प को केवल तभी बदलना चाहिए जब आप अपने आवेदन को तैनात या निर्मित करते हैं। अन्यथा हर बार उपयोगकर्ता ताज़ा पृष्ठ या अपने आवेदन में अन्य पृष्ठों पर स्विच करता है। ब्राउज़र आपके सभी स्टाइलशीट और जावास्क्रिप्ट को फिर से डाउनलोड करेगा, जो अच्छा नहीं है
तरुण

2
पृष्ठ के प्रदर्शन पर क्या प्रभाव पड़ता है? पेज को लोड करने में कितना विलंब हो सकता है?
दुर्गेश सोनावने

28

आपका समाधान काम करता है। यह वास्तव में काफी लोकप्रिय है।

यहां तक ​​कि स्टैक ओवरफ्लो एक समान विधि का उपयोग करता है:

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

v=6184संभवतः एसवीएन संशोधन संख्या कहां है।


यह स्वीकृत उत्तर में वर्णित एक से अधिक कर दृष्टिकोण होगा। हर बार पृष्ठ पर दिए गए फ़ाइल के SVN संस्करण की जाँच करना एक प्रदर्शन ओवरहेड है, विशेष रूप से समय के साथ उपयोगकर्ताओं की संख्या बढ़ जाती है।
नियोलिस्क

4
आप निर्माण के दौरान संशोधन संख्या प्राप्त कर सकते हैं, इसे एक फ़ाइल में लिख सकते हैं (जैसे कि आंशिक .cs फ़ाइल), उस फ़ाइल को अपनी परियोजना में शामिल करें, इसलिए आपको इसे रनवे पर svn से पढ़ने की आवश्यकता नहीं है। मैं अपने विधानसभा में संशोधन संख्या डालने के लिए msbuild के साथ इस दृष्टिकोण का उपयोग किया है। svn से फ़ाइलें।
रमज़ान बिनरबासी

2
वैश्विक संस्करण / संशोधन संख्या का उपयोग करने में कम से कम एक खामी होती है: वेबसाइट अपडेट प्रकाशित करना सभी .js और .css फ़ाइलों के लिए ब्राउज़र कैश को अमान्य कर देता है, न कि केवल उन बदलावों को। यह संभवतः अधिकांश अनुप्रयोगों में मायने नहीं रखता है, लेकिन मैं इसे पूर्णता के लिए उल्लेख करता हूं।
एडम टेगेन

यदि आप किसी असेंबली या बिल्ड के दौरान अपने असेंबली के संस्करणों को स्वचालित रूप से अपडेट करते हैं, तो उस संख्या के लिए मामूली संस्करण का उपयोग किया जा सकता है।
kristianp

28

में ASP.NET कोर (MVC 6) इस के माध्यम से बॉक्स से बाहर काम करता है asp-append-versionटैग सहायक:

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

1
हमारी जानकारी में लाने के लिये धन्यवाद! मैं इसे पहले नहीं जानता था!
फेडेरिको नवरेट

18

यदि आप अपने JS / CSS के लिए बंडलों का उपयोग करते हैं, तो ASP.NET MVC आपके लिए इसे संभाल लेगा। यह स्वचालित रूप से आपके बंडलों के लिए एक GUID के रूप में एक संस्करण संख्या को जोड़ देगा और बंडल को अपडेट किए जाने पर केवल इस GUID को अपडेट करेगा (किसी भी स्रोत फ़ाइल में परिवर्तन है)।

यदि आपके पास जेएस / सीएसएस फाइलों का एक टन है तो यह भी मदद करता है क्योंकि यह सामग्री लोड समय में बहुत सुधार कर सकता है!

यहाँ देखें


क्या आपका मतलब है कि अगर हम एमवीसी एप्लिकेशन में बंडलों का उपयोग करते हैं, तो यहां पोस्ट किए गए उत्तर में विधियों की कोई आवश्यकता नहीं है? यदि हां, तो बंडलिंग वास्तव में बहुत अधिक महत्वपूर्ण है जो मैंने कभी सोचा है। क्या आप हमें इन मुद्दों के बारे में स्पष्ट कर सकते हैं? धन्यवाद।
जैक

1
हाँ बिल्कुल। जब तक आपकी स्क्रिप्ट को एक बंडल में शामिल किया जाता है, तब तक यह प्रत्येक बंडल के लिए स्वचालित रूप से एक संस्करण संख्या उत्पन्न करेगा जब बंडल के स्रोत फ़ाइलों में से किसी में परिवर्तन का पता लगाया जाता है।
jonesy827

और मत भूलो कि आप अभी भी एक डेवलपर के रूप में सिरदर्द हैं। ASP.NET बंडलिंग डीबगिंग और विकास के दौरान किसी भी तरह से मदद करता है।
it3xl

12

इसके लिए asp.net में एक अंतर्निहित तरीका है: बंडलिंग । बस इसका उपयोग करें। प्रत्येक नए संस्करण में अद्वितीय प्रत्यय होगा "? V = XXXXXXX"। डिबग मोड में, वेब सेटिंग में स्विच करने के लिए बंडलिंग बंद है।

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

या मेथड रजिस्टरबंडल्स (बंडलकॉलिनेशन बंडल) में जोड़ें:

BundleTable.EnableOptimizations = true;

उदाहरण के लिए:

बंडलकॉन्फ़िग .cs:

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

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

_Loutout.cshtml:

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

लेकिन यह केवल रिलीज या प्रोडक्शन के माहौल में काम करेगा। डिबग मोड चालू होने पर विकास के बारे में क्या? क्या बंडल अभी भी इस समस्या को ठीक करता है?
VAAA

हाँ, बंडलिंड डेवलपर्स को आसान नहीं बनाता है। प्रत्येक स्क्रिप्ट बदलने के बाद आपको Ctrl-F5 दबाना होगा। और अगर आपके पास फ़्रेम्स हैं तो यह और भी मज़ेदार होगा।
it3xl

6

प्रश्न में ऑप द्वारा दिए गए उत्तर की तुलना में इसका सरल उत्तर है (दृष्टिकोण समान है):

Web.config में कुंजी को परिभाषित करें:

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

एप्सेटिंग से कॉल को सीधे aspx पेज से करें:

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

मुझे यह पसंद है, लेकिन मुझे इस बात की चिंता है कि इस समाधान में वोटों की इतनी
कमी

@SimplyInk मुझे नहीं पता, लेकिन 20 अलग-अलग उत्तर हैं, ताकि इसके साथ कुछ हो सके। अगर यह काम करता है और आप इसे पसंद करते हैं, तो इसे बेझिझक उठाएं।
जैकएबिटर

4

एडम टेगन के जवाब के आधार पर , एक वेब फॉर्म एप्लिकेशन में उपयोग के लिए संशोधित।

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

Aspx मार्कअप में:

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

और प्रदान किए गए HTML में, यह इस प्रकार दिखाई देता है

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

2
अरे! आपका उदाहरण काम कर रहा है, लेकिन आपको कैशिंग संदर्भों को हटा देना चाहिए या कैश का उपयोग करने के लिए कोड को ठीक करना चाहिए क्योंकि यह भ्रमित हो सकता है कि आप इसका उपयोग क्यों कर रहे हैं। कैश का उपयोग करने के लिए आपको संदर्भ का उपयोग करके फ़ाइल के संस्करण को कैश में जोड़ना चाहिए। कैश का संदर्भ दें। संदर्भ में विधि। कैश [फ़ाइल का नाम] == नल। यदि संदर्भ। कैश [फ़ाइल नाम]! = अशक्त है तो आपको कैश्ड मान वापस करना चाहिए (संदर्भ। कैश [फ़ाइल नाम])
फ्लाविया ओब्रेजा

1
फ्लाविया, मुझे लगता है कि आपका स्पष्टीकरण समझ में आता है, और मुझे लगता है कि यह एक सरल, अधिक कुशल कार्यान्वयन है। उपयोगी टिप्पणी और प्रतिक्रिया पोस्ट करने के लिए धन्यवाद।
ब्रायन

4

दिलचस्प बात यह है कि इस साइट के पास कुछ प्रॉक्सी सेटअपों के संबंध में आपके द्वारा वर्णित दृष्टिकोण के साथ समस्याएँ हैं, भले ही यह विफल-सुरक्षित होना चाहिए।

इस मेटा स्टैक अतिप्रवाह चर्चा की जाँच करें ।

तो इसके प्रकाश में, यह समझ में नहीं आ सकता कि अपडेट करने के लिए GET पैरामीटर का उपयोग न करें, लेकिन वास्तविक फ़ाइल नाम:

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

हालांकि यह करने के लिए अधिक काम है, क्योंकि आपको वास्तव में फ़ाइल बनाना होगा, या इसके लिए एक URL फिर से लिखना होगा।


4

मैं एक सरल एक लाइनर चाहता था ताकि कैश को बस्ट करने के लिए पथ को अद्वितीय बनाया जा सके। यह मेरे लिए काम किया:

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

यदि पिछली बार जब यह पृष्ठ पर लोड किया गया था तब से फाइल को संशोधित किया गया है, तो ब्राउज़र अपडेट की गई फ़ाइल को खींच लेगा।

यह फ़ाइल last modifiedसे स्टैम्प उत्पन्न करता है .jsऔर संस्करण के बजाय वहां इसे चक करता है जिससे पहुँच प्राप्त करना आसान नहीं हो सकता है।

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

एक अन्य विकल्प फाइल का चेकसम प्राप्त करना हो सकता है।


1
ऐसा करने का सबसे आसान तरीका, और शायद सबसे कम ओवरहेड।
टोनी हिंकले

1
सही समाधान। मैंने यह भी सुनिश्चित करने के लिए क्रोम 70, फ़ायरफ़ॉक्स 63 और IE 11 का परीक्षण किया कि कैशिंग वास्तव में काम कर रहा था। यह है। यह केवल फ़ाइल के नए संस्करणों पर कैशिंग का पर्दाफाश करता है, कम से कम ब्राउज़रों के नवीनतम संस्करणों पर। मैंने कहीं और उल्लेख किया है कि कुछ ब्राउज़रों ने हर फ़ाइल को एक querystring (?) के साथ पुनः लोड किया। हो सकता है कि इसका इस्तेमाल किया गया हो या शायद यह अभी भी सफारी और ओपेरा के साथ सच है। डीके।
ब्रैड मैथ्यूज

3

यहाँ एक दृष्टिकोण है जो ASP.NET 5 / MVC 6 / vNext के साथ काम करता है ।

चरण 1: इस थ्रेड में अन्य उत्तरों के समान, फाइल के अंतिम लिखने के समय को वापस करने के लिए एक क्लास बनाएं। ध्यान दें, इसके लिए ASP.NET 5 (या अन्य) निर्भरता इंजेक्शन की आवश्यकता है।

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

चरण 2: रजिस्टर सेवा के अंदर इंजेक्ट किया जा करने के लिए startup.cs :

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

चरण 3: फिर, ASP.NET 5 में, इस तरह से _Layout.cshtml जैसे लेआउट दृश्य में सीधे सेवा को इंजेक्ट करना संभव है :

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

कुछ परिष्करण स्पर्श हैं जो भौतिक रास्तों को बेहतर ढंग से संयोजित करने और वाक्यविन्यास के अनुरूप शैली में फ़ाइल नाम को संभालने के लिए किए जा सकते हैं, लेकिन यह एक प्रारंभिक बिंदु है। आशा है कि यह ASP.NET 5 पर जाने वाले लोगों की मदद करता है।


इस व्यवहार वास्तव में बॉक्स से बाहर समर्थित है, देखना मेरा उत्तर
metalheart

3

मैंने अपने एस्पनेट 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;
    }
}

फिर वास्तविक विचारों में:

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

यह मेरे लिए सभी ब्राउज़रों में काम करता है। यहाँ मैंने PHP का उपयोग यादृच्छिक संख्या उत्पन्न करने के लिए किया है। आप अपनी स्वयं की सर्वर साइड भाषा का उपयोग कर सकते हैं


अच्छा जवाब है, लेकिन अगर आप एडम ने जो समझाया, उस पर विचार न करें, तो एएसपी एमवीसी थोड़ा समस्याग्रस्त हो सकता है क्योंकि मैंने इसे आज़माया था और अगर आप एमवीसी के साथ काम करते हैं तो बंडल फ़ोल्डर इसे नहीं पहचानता है। लेकिन सुझाव के लिए धन्यवाद!
फेडेरिको नवरेट

2

उपर्युक्त उत्तर से शुरू करके मैंने CSS फाइलों के साथ सहायक काम करने के लिए भी थोड़ा सा कोड संशोधित किया और हर बार जब आप फ़ाइलों में कुछ बदलाव करते हैं और न केवल जब आप बिल्ड करते हैं तो एक संस्करण जोड़ते हैं

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

फ़ाइल संशोधित समय प्राप्त करें, जैसा कि नीचे दिखाया गया है

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

इसे क्वेरिस्ट्रिंग के रूप में इनपुट के साथ जोड़ें

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

इसे मार्कअप से कॉल करें।

एमवीसी एक्सटेंशन हेल्पर दृष्टिकोण

एक विस्तार विधि जोड़ें

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

    }
}

इस नाम स्थान को 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>

इसे देखने के रूप में उपयोग करें

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

1

.NET वेब फ़ॉर्म डेवलपर्स के लिए पहले से सुझाए गए सरलीकृत सुझाव और कोड प्रदान करना।

यह दोनों रिश्तेदार ("~ /") और संसाधन के लिए फ़ाइल पथ में पूर्ण यूआरएल स्वीकार करेगा।

एक स्थिर एक्सटेंशन क्लास फ़ाइल में रखें, निम्नलिखित:

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

और फिर इसे अपने मास्टर पेज में इस तरह से कॉल करें:

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

अच्छा तरीका भी!
फेडेरिको नवरेट

0

उपरोक्त उत्तर के आधार पर मैंने CSS और 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;
        }
    }
}

इसके बजाय कुछ लिखने की तरह:

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

अब आप लिख सकते हैं:

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

यानी बस के Url.Contentसाथ बदलें Url.VersionedContent

उत्पन्न URL कुछ इस तरह दिखते हैं:

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

यदि आप एक्सटेंशन क्लास का उपयोग करते हैं, तो आप MapPathकॉल contentPathफ़ाइल के काम न करने की स्थिति में त्रुटि से जोड़ना चाहते हैं, क्योंकि यह एक भौतिक फ़ाइल नहीं है।


0

मैं उसी तरह का उपयोग करता हूं जैसे आप प्रत्येक पृष्ठ को संशोधित किए बिना कर रहे हैं। जोड़ा गया एक PreRender घटना मास्टर फ़ाइल है। यह एक जगह पर मेरा तर्क रखता है और js और 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

आप स्क्रिप्ट या शैलियाँ की DefaultTagFormat संपत्ति को ओवरराइड कर सकते हैं।

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 एप्लिकेशन में इस समस्या को हल करने के लिए, मैंने एक एक्सटेंशन बनाया और फिर मास्टर पेज में कॉल किया।

अधिक जानकारी के लिए, आप लिंक पर जा सकते हैं ।


0

नीचे अवधारणा द्वारा .net आवेदन में सीएसएस संस्करण को लागू करने के लिए आसान और स्मार्ट तरीका .. बैक-एंड कोड लिखने की कोई आवश्यकता नहीं है।

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

हर पेज रेंडर में यह wil Force डाउनलोड होता है, भले ही फाइलें बिल्कुल भी नहीं बदली गई हों।
थानासिस आयोनिडिस

@ThanasisIoannidis यह उन फाइलों का उपयोग कर सकता है जहां फाइलें नियमित रूप से बदलती रहती हैं। एक अन्य विकल्प web.config में appVersion कुंजी जोड़ें और फ़ाइलों के नाम के साथ उपयोग करें .. लेकिन जब आप उत्पादों के लिए एप्लिकेशन जारी करते हैं तो आपको अपडेट करने की आवश्यकता होती है।
संतोष

-1

इसे इस तरह से करने के साथ मुख्य समस्या यह है कि आपको अपने कोड में हर बार अपने सीएसएस या जेएस फाइलों में कोई बदलाव करने के लिए अपने वर्जन नंबर को अपडेट करने के लिए याद रखना होगा।

ऐसा करने का संभवतः बेहतर तरीका यह है कि आप अपनी प्रत्येक सीएसएस या जेएस फाइलों के साथ एक गारंटीकृत अद्वितीय पैरामीटर सेट करें, जैसे:

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

यह फ़ाइलों को सर्वर से अनुरोध करने के लिए हर बार मजबूर करता है, जिसका अर्थ यह भी है कि आपकी साइट पेज लोड होने पर उतनी प्रदर्शनशील नहीं होगी, क्योंकि उन फ़ाइलों को कभी कैश नहीं किया जाएगा, और हर बार अनावश्यक बैंडविड्थ का उपयोग करेगा।

अनिवार्य रूप से, यदि आप बदलाव किए जाने के बाद हर बार संस्करण संख्या को अपडेट करना याद रख सकते हैं, तो आप यह कर सकते हैं कि आप इसे कैसे कर रहे हैं।


9
और बैंडविड्थ की प्रचुर मात्रा का उपयोग करता है।
डैरेन कोप

2
ठीक है, आप प्रत्येक पृष्ठ लोड पर JS का एक नया संस्करण नहीं चाहते हैं ... आप बस चाहते हैं कि ब्राउज़र हर बार एक नए संस्करण की तलाश करे, जब आपके पास वास्तव में एक अद्यतन संस्करण हो।
किंगडैंगो

यह विकास में रहते हुए 50KB सीएसएस फ़ाइल पर एक अस्थायी समाधान के लिए पूरी तरह से स्वीकार्य है। +1
कॉल्स

-2

ASP.NET पृष्ठों के लिए मैं निम्नलिखित का उपयोग कर रहा हूँ

इससे पहले

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

AFTER (बल पुनः लोड)

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

DateTime.Now.Ticks को जोड़ना बहुत अच्छी तरह से काम करता है।


हाँ, समस्या बैंडविड्थ के साथ है - जैसे ऊपर की टिप्पणियों में stackoverflow.com/a/2185918/59508
kiev
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.