Archive
HowTo: Reset browser cache of CSS files upon ASP.net MVC app publish
On an ASP.net MVC webapp I’m maintaining, I had the issue that due to caching of older CSS (stylesheet) files in the browser, if the user didn’t press F5/refresh, it wasn’t showing you some message (since I had added the class .center-horiz-vert in the CSS that didn’t exist in the older cached css the browser had).
Instead of changing web.config to stop cachine of CSS files (in which case it would bring the CSS on every page load which is an overkill), I expanded on an idea mentioned by Maxim Kornilov on SO (https://stackoverflow.com/a/12992813/903783), on making the CSS URLs webapp version specific.
I added a fake version parameter to the URLs with the build number as value so that till I publish a new build the browser caches the CSS, but when I upload a new build it brings the new one since it cache with the url as a key (that now includes the build number as a dummy url parameter that the webserver will ignore and just fetch the CSS file when requested)
Maxim’s example was in ASP/ASP.net WebForms syntax instead of MVC’s and Razor Pages’ newer Razor syntax), so I contributed my solution for the case of an ASP.net MVC webapp that wants to serve a fresh copy of CSS files on every new build that you publish (will do this whether the CSS file has changed or not) so that browsers don’t use older cached copies of the file. Obviously this expands to any kind of files you link/load into your webpages via a URL.
1) Added to the webapp’s main class (was called MvcApplication) in Global.asax.cs
#region Versioning
public static string Version =>
typeof(MvcApplication).Assembly.GetName().Version.ToString();
//note: syntax requires C# version >=6
public static DateTime LastUpdated =>
File.GetLastWriteTime(typeof(MvcApplication).Assembly.Location);
#endregion
the someProperty => someReadOnlyExpression syntax is just shorthand for someProperty { get { return … ;} } possible since C# 6
2) in its Content/_Layout.cshtml file I used to have the following to show build number and build datetime (based on the webapp’s main assembly) on the page footer:
Version @ViewContext.Controller.GetType().Assembly.GetName().Version
(@string.Format("{0:yyyy/MM/dd-HH:mm:ss}",
@File.GetLastWriteTime(ViewContext.Controller.GetType().Assembly.Location)))
which I changed to the simpler:
Version @somewebappname.MvcApplication.Version
(@string.Format("{0:yyyy/MM/dd-HH:mm:ss}",
somewebappname.MvcApplication.LastUpdated))
3) it was loading the CSS via hardcoded link in _Layout.cshtml (still refactoring it) which I changed to:
<link href='@Url.Content("~/Content/Site.css?version=" +
somewebappname.MvcApplication.Version)' rel="stylesheet" type="text/css" />
so if one right-clicks in the webpage and they do view source they see:
<link href='/Content/Site.css?version=2.1.5435.22633'
rel="stylesheet" type="text/css" />
that is the CSS url is version specific thanks to the dummy parameter version
If a random number was used instead it would fetch the CSS at every page load which is usually undesired, especially if you are already pushing a new webapp build instead of individual page changes to the web server (so that you do have access to a build number that you can inject into URLs).
Note that to achieve auto-incrementing of build number, at Properties/AssemblyInfo.cs I have (see How to have an auto incrementing version number (Visual Studio)?):
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision
// and Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.*")]
// don't use boh AssemblyVersion and AssemblyFileVersion with auto-increment
Fix: Reset forgotten Windows Phone pin remotely if locked out of it
I got an older Lumia 930 phone (nice big display and 20MP camera, Windows Mobile 8.1 upgradeable to Windows 10, main shortcoming is that it doesn’t have microSD slot) on big discount the other day, but after upgrading it to Windows 10 I accidentally entered the wrong PIN code at login an it managed to lock permanently.
I was having the deadlocking situation where after it locked asking me to reboot, at each reboot (even tried resetting with power+vol down for 10sec), it was saying the same thing again and again.
Luckily I had already activated a Microsoft account (was required at Win8.1 in order to download the Windows upgrade advisor app from the store), so following the guidance at https://answers.microsoft.com/en-us/mobiledevices/forum/mdlumia-mdsettings/how-to-reset-phone-if-i-forgot-my-lockscreen/ff4d7ba3-d301-4392-b05a-46bac68dcc69 and some other forum discussions, I went to http://account.microsoft.com, then at the Devices section, selected to see more info on that specific phone and then from Find My Phone I choose to lock it with a new 6-digit pin.
There, it asks you to also enter a message that is supposed to display to the user of the phone, but haven’t seen it appear. However it does make it to change it successfully.
For changing the pin remotely the phone obviously needs to have wifi or data access active (if it doesn’t and doesn’t allow you to set it without entering a code, try plugging it via USB to a Windows 10 computer first or if you’ve set it up to connect automatically to open hotspots find one such). Else will need to have a SIM and number and be connected (correct SIM pin entered) to mobile (GSM etc.) network. The lock phone pane at account.microsoft.com does ask you if the phone has a number assigned to it or not, to send some special locking SMS I guess.