Archive
HowTo: URL rewrite to redirect HTTP to HTTPS for non-local address
Below is an answer on how to redirect from HTTP to HTTPS using the URL Rewrite module for IIS, but ignoring local addresses used when debugging one’s app. Just contributed at https://stackoverflow.com/a/75898224/903783.
Needed it for an ASP.net MVC app I’m maintaining, since due to updated policy that the authenticating organisation had decided for the SSO (Apereo CAS) configuration, we couldn’t redirect anymore back to a non-HTTPs URL (had the user used plain HTTP to access our app that is), after signing in succesfully via the SSO.
Combined URL Rewrite based answers from How to redirect HTTP to HTTPS in MVC application (IIS7.5) and from the question’s page on StackOverflow, and added "127.0.0.1" apart from “localhost” for the ignored sites.
Note that the URL Rewrite approach is by far the simplest one to add and should kick in at the web server level before the web app has any chance to process the request.
I also see {REQUEST_URI} being used instead of {R:1} and pattern="^OFF$" instead of pattern="off".
At pattern added the ignoreCase="true" too, though it might be the default (same goes for enabled="true" for the rule, handy to have there if you want to turn some rule off when debugging some rule chain)
However, wondering based on https://serverfault.com/questions/224039/iis-url-rewrite-http-to-https-with-port/418530#418530 if one needs to use SERVER_NAME instead of HTTP_HOST in the pattern if non-default ports are used and specify the port in the Redirect url too
<system.webServer>
<!-- … -->
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect (excluding localhost)" enabled="true"
stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{HTTP_HOST}" pattern="localhost" negate="true" />
<add input="{HTTP_HOST}" pattern="127.0.0.1" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent"
url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
<!-- … -->
</system.webServer>
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: jQuery’s jqGrid search UI custom styling
Lately, I’ve got the task of maintaining/extending an ASP.net MVC web application that is using jQuery’s jqGrid for data grids on its UI. First thing I noticed was how confusing the search UI on the grid’s header was:
Those symbols on the left-side of each column’s searchbox are for the type of search (e.g. contains, doesn’t contain, equals, starts with, doesn’t start with, ends with, doesn’t end with).
Bit too many options and using programming-related symbols that probably intimidate several users in my opinion:
But the worse is the “x” button (that clears the searchbox) on the right of each searchbox, that combined with the search-type symbols makes the whole search bar look like some strange mathematical expression.
So using the browser dev tools (F12) and some CSS rules I quickly restyled that search bar to make it more appealing UI/UX wise:
Added a border around the “x” button that clears the searchbox and offseted using a negative margin so that the searchbox and it fuse together visually on their sides. Also made the search-type symbol (that opens the search-type selection popup when clicked) of lighter color. It may look a bit-like some disabled thing like that, but at least it should confuse average users less with its use of technical symbols like that.
Just need to add the rules above at the ASP.net MVC app’s Site.css (probably to be found at the Content subfolder of the webapp) and remember to press F5/Refresh in one’s browser in case the old styling still appears due to caching.
Update #1:
I noticed on older versions of Windows (other than Windows 10 that is) that bevels were showing at the text inputs, leading to this ugly effect:
So I had to add some more rules to remove the bevel borders and use a consistent border color.
Removing the bevels seemed to also remove the inner padding of the text inputs, so added a padding of 2px and some box-sizing rules to make sure the padding doesn’t affect the input’s size.
/* OS-independent styling for input and textarea borders */
textarea,
input[type="text"],
input[type="password"] {
border-style: solid;
border-width: 1px;
border-color: gray;
padding: 2px;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
Update #2:
After recently updating some jQuery related NuGet packages in that ASP.net project, I noticed the [x] button was showing a bit higher up at the bottom compared to the search box. The fix to that was to add padding-bottom: 1px; at the CSS declaration for clearsearchclass in Content/Site.css
a.clearsearchclass {
border-width: 1px;
border-style: solid;
/* border-left-style: none; */
margin-left: -3px;
padding-bottom: 1px; /* seems to be needed with newer jQuery.UI */
background: whitesmoke;
border-color: gray;
}