Archive

Author 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: “A numeric comparison was attempted” at VS build (Costura.Fody)

After upgrading from Visual Studio 2017 to Visual Studio 2019 I was able to update NuGet packages Fody and Costura.Fody of a solution that needed them (to package assembly DLLs inside console EXEcutables) and the solution was rebuilding fine.

However after I synced the solution via a Git repository on another machine and installed the newer Visual Studio there too, I rebuilt the solution in order to fetch/rebuild NuGet packages too and although everything seemed to rebuild fine, when I was using a plain build instead of a rebuild all I was getting at Errors dialog for each project that was using Costura.Fody:

Error

A numeric comparison was attempted on "$(MsBuildMajorVersion)" that evaluates to "" instead of a number, in condition "($(MsBuildMajorVersion) < 16)".  

To fix this I had to uninstall and reinstall Costura.Fody NuGet package (it wasn’t needed to uninstall/reinstall the Fody NuGet package itself) on the solution’s projects that were using it and then all was rebuilding/building fine again on that other machine.

Fix: Invalid Firmware Image at Dell Inspiron 3537 BIOS update

For some time now I was trying to update the BIOS of an older Dell Inspiron 3537 laptop from inside Windows (with the InsydeFlash application that the respective Dell update package employs), only to get a blue screen saying Invalid Firmware Image upon reboot and the BIOS update was skipped every time.

Since that update was fixing a critical security issue (Intel Security Advisory INTEL-SA-00115 – CVE-2018-3639 & CVE-2018-3640), I decided to do some more research on it. I eventually came to the conclusion that since I had A9 BIOS version, I needed to install BIOS version A10 first (which addresses CVE-2017-5715 and associated Intel Reboot issue), then try the BIOS version A11 update that the Dell Support online was offering.

Luckily there was a Dell BIOS update guide that was suggesting to visit Dell downloads catalog to find older updates, from where I found all Dell Inspiron 3537 updates and was able to locate the A10 BIOS update.

Updating the BIOS from version A9 (the version I had, as displayed at “Current BIOS” field on the InsydeFlash UI) to A10 and then after reboot from A10 to A11 with the respective update executables worked fine. Can confirm the update is done by launching the update once more and then just Cancel.

image

HowTo: round a number up to N decimal digits in Javascript

Was just trying to round-off some Google Maps coordinates for display in Javascript up to 3 decimal digits and that was a bit like a blast from the past (the end of the ‘90s to be more accurate)…

So here’s my contributed answer at:
https://stackoverflow.com/questions/2221167/javascript-formatting-a-rounded-number-to-n-decimals

This works for rounding to N digits (if you just want to truncate to N digits remove the Math.round call and use the Math.trunc one):

function roundN(value, digits) {
   var tenToN = 10 ** digits;
   return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
}

Had to resort to such logic at Java in the past when I was authoring data manipulation E-Slate components. That is since I had found out that adding 0.1 many times to 0 you’d end up with some unexpectedly long decimal part (this is due to floating point arithmetics).

A user comment at Format number to always show 2 decimal places calls this technique scaling.

Some mention there are cases that don’t round as expected and at http://www.jacklmoore.com/notes/rounding-in-javascript/ this is suggested instead:

function round(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}

image

HowTo: remove Javascript imports from OpenLayers map examples

OpenLayers is a fine alternative to the map visualization part of Google Maps Platform, however many of its examples sometimes use features from future and server-side Javascript versions, like “imports”.

Based on lou’s answer at https://stackoverflow.com/questions/51093964/why-examples-dont-work-a-struggle-with-imports/56549364, here’s a fix I just did to make the Marker animation example work when you just copy-paste the example code in an .html file without any pre-processing:

<head>
<meta charset="UTF-8">
<title>Marker Animation</title>
<link rel="stylesheet" href=https://openlayers.org/en/v5.3.0/css/ol.css 
type="text/css"> <!-- The line below is only needed for old environments like
Internet Explorer and Android 4.x --> src="https://cdn.polyfill.io/v2/polyfill.min.js?
features=requestAnimationFrame,Element.prototype.classList,URL">
MAKE THE ABOVE A SINGLE ROW
http://br

MAKE THE ABOVE A SINGLE ROW
</head> <body>
<label for="speed"> speed:&nbsp; <input id="speed" type="range" min="10" max="999" step="10" value="60"> </label> <button id="start-animation">Start Animation</button> <script> var Feature = ol.Feature; //import Feature from 'ol/Feature.js';
var Map = ol.Map; //import Map from 'ol/Map.js';
var View = ol.View; //import View from 'ol/View.js';
var Polyline = ol.format.Polyline;
//import Polyline from 'ol/format/Polyline.js';
var Point = ol.geom.Point; //import Point from 'ol/geom/Point.js';
var {Tile, Vector} = ol.layer;
//import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js'; var TileLayer = Tile; var VectorLayer = Vector;
//var BingMaps = ol.source.BingMaps;
//import BingMaps from 'ol/source/BingMaps.js';
var VectorSource = ol.source.Vector;
//import VectorSource from 'ol/source/Vector.js';
var {Circle, Fill, Icon, Stroke, Style} = ol.style;
//import {Circle as CircleStyle, Fill, Icon, Stroke, Style}
// from 'ol/style.js'; var CircleStyle = Circle; // This long string is placed here due to jsFiddle limitations. // It is usually loaded with AJAX. var polyline = [ ...

and to use an ESRI sattelite map or OpenStreetMap (plain) map instead of Bing Maps one (which requires a key), do this extra edit to the Marker animation example:

  var map = new Map({
    target: document.getElementById('map'),
    loadTilesWhileAnimating: true,
    view: new View({
      center: center,
      zoom: 10,
      minZoom: 2,
      maxZoom: 19
    }),
    layers: [
      new TileLayer({
        source:
            //new ol.source.OSM()

            new ol.source.XYZ({
              attributions: ['Powered by Esri',
                             'Source: Esri, DigitalGlobe, GeoEye, \
Earthstar Geographics, CNES/Airbus DS, USDA,\
USGS, AeroGRID, IGN, and the GIS User Community'], attributionsCollapsible: false,
url:
'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/
MapServer/tile/{z}/{y}/{x}',

MAKE THE ABOVE A SINGLE ROW
maxZoom: 23 }) /* new BingMaps({ imagerySet: 'AerialWithLabels', key: 'Bing Maps Key from http://www.bingmapsportal.com/ here' }) */ }), vectorLayer ] });

Here’s the modified result:

image

HowTo: Use latest C# features in MVC5 Razor views (.cshtml)

Having recently updated an ASP.net MVC web app from MVC4 to MVC5 and from .NET 4.5 to .NET 4.7.2 I was expecting Razor views (.cshtml files) to use the latest C# compiler, especially since at Properties/Build/Advanced option for the web project one read “C# latest major version (default)”.

However that was not the case and trying to use newer C# language features like the ?. ternary conditional operator or interpolated strings (or nameof etc.) would show errors like

Feature ‘interpolated strings’ is not available in C# 5. Please use language version 6 or greater.

Luckily there is a workaround for using the latest C# compiler in MVC5. Just need to add the NuGet package https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/ to one’s project as explained at https://dusted.codes/using-csharp-6-features-in-aspdotnet-mvc-5-razor-views. Alternatively one could move their project to ASP.net Core, which is a more drastic move though.

After doing it I started seeing Intellisense issues in .cshtml like:

The type ‘Expression<>’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Core …

Tried to add the System.Core assembly to the project, but wasn’t allowed (it said the Build system was adding it). Adding System.Core as a NuGet package would mean moving to .NET Core which I wasn’t ready to try with that project yet.

Seems there was an easy solution to that, just closed and reopened the Visual Studio solution and did a Rebuild and all was fine after that.

Categories: Posts Tags: , , , , , ,

Fix: Word print view showing no margins and pages appear collated

I’m often asked by friends and family to assist them on frustrating technical issues they can’t resolve by themselves. Thanks to remote access / support software like TeamViewer, this is a piece of cake nowadays.

The solution to such problems isn’t always straightforward though. Just came across a Microsoft Word installation where suddenly the Print view had started using a strange layout with grid lines in the background, no margins and with the consecutive pages showing collated as you scrolled in the document. This defeats the whole WYSIWYG (What-You-See-Is-What-You-Get) concept that most people like about modern word processors.

Removing the grid lines is straightforward from the View menu (Appearance section), but to fix the other issues, the only way I found was, at the Zoom section of the View menu, to change to Multiple Pages, then change to Single Page, then Set Zoom to 100% and finally Set zoom to Page Width. After all is fixed you can then switch those settings to how you prefer them (say zoom 100% instead of page width).

If that doesn’t work, you could try resetting Microsoft Word user settings to their defaults, both an automated and a manual way is offered at:

https://support.microsoft.com/en-us/help/822005/how-to-reset-user-options-and-registry-settings-in-word

Categories: Posts Tags: , , , , , ,
%d bloggers like this: