Archive

Archive for the ‘Posts’ Category

HowTo: include MVC model property Display name in Required validation message

Just came across this validation error display in an MVC app I’ve recently started maintaining. The required input field validation seemed to not be localized, resulting in a mixed English and Greek (from the field’s Display name) message:

image

Looking at the MVC model I noticed they were using [Required] attributes for the userName and password properties, together with [Display(Name = "…")] for the displayed property title

public class LoginModel
  {
     [Required]
     [Display(Name = "Όνομα Χρήστη")]
     public string userName { get; set; }

     [Required]
     [DataType(DataType.Password)]
     [Display(Name = "Κωδικός")]
     public string password { get; set; }

     //…

That was changed to:

public class LoginModel
  {
     [Required(ErrorMessage = "Το {0} είναι απαραίτητο.")]
     [Display(Name = "Όνομα Χρήστη")]
     public string userName { get; set; }

     [Required(ErrorMessage = "Το {0} είναι απαραίτητο.")]
     [DataType(DataType.Password)]
     [Display(Name = "Κωδικός")]
     public string password { get; set; }

resulting in a fully localized validation error message with the respective property’s Display name auto-inserted in the validation ErrorMessage, thanks to the {0} used in the message string:

image

Note there’s also the lazy route like in this property:

[Display(Name = "Περίοδος Εγγύησης(Έτη):")]
[Required(ErrorMessage = "Απαραίτητο πεδίο")]
public int warrantyPeriod { get; set; }

where you just say something like “Required field” in the localized error message. This however will work only when you always show the error message next to the input field that fails to pass validation.

If you want to also show a validation summary say at the beginning and/or the end of the page (depending on where your submit button is), you’ll end up with an error summary that may just contain multiple entries of “Required field” text without any indication on what field it was (which would be practically useless that is).

Note that sometimes due to lack of space in a webpage (say if you have lots of input fields in a grid) you can only show say red “*” near input fields that have validation errors and explain them more in the tooltips and in an error summary control.

Even better you can use resource strings to avoid error message string duplication. That approach, though a bit more verbose as implemented in ASP.net means easier centralized maintenance and localization from a per locale/language resource file and less typos or slightly different error messages for the same thing. See example and related screenshots at https://stackoverflow.com/a/22849638

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:

image

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:

image

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:

image

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:

image

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

Categories: Posts Tags: , , , , , , , , ,

Getting resulting SQL string from parametric ADO.net SqlCommand

Microsoft is suggesting to always use Named parameters with SqlCommands for security reasons (to avoid SQL injection exploits), but they haven’t thought of providing a property at SqlCommand to give you back the result SQL so that you can have your app log it without resorting to SQL Server for that logging.

Found a solution at CommandAsSQL project on GitHub and the discussion that brought it to life at https://stackoverflow.com/questions/265192/get-the-generated-sql-statement-from-a-sqlcommand-object/

That solution was only for the case where the type of the SqlCommand was StoredProcedure, but needed to cover non-Stored procedures too (aka type Text of SqlCommand), so I augmented that library with this logic:

    private static void CommandAsSql_Text(this SqlCommand command, 
System.Text.StringBuilder sql) { string query = command.CommandText; foreach (SqlParameter p in command.Parameters) query = Regex.Replace(query,
"\\B" + p.ParameterName + "\\b", p.ParameterValueForSQL());
sql.AppendLine(query); }

The pull request is at: https://github.com/jphellemons/CommandAsSql/pull/3/commits/527d696dc6055c5bcf858b9700b83dc863f04896

The Regex idea was based on @stambikk’s and EvZ’s comments at that StackOverflow thread and the "Update:" section of https://stackoverflow.com/a/2544661/903783 that mentions "negative look-behind assertion".

The use of \B instead of \b for word boundary detection at the start of the regular expression is because the p.parameterName will always start with a "@" which is not a word character.

Note that ParameterValueForSQL() is an extension method defined at the CommandAsSql library to handle issues like single-quoting string parameter values etc. It may have a bug with its date handling currently though, will submit an issue on that

Btw, other promising piece of code is at https://github.com/jeroenpot/SqlHelper/blob/master/Source/Mirabeau.MsSql.Library/SqlGenerator.cs (mentioned at an answer in this thread). Probably could merge code from CommandAsSql and SqlGenerator if one finds something not working at one or the other.

Gotcha: VBScript DropHandler doesn’t support Unicode filenames

It seems VBScript (.vbs) script file’s DropHandler on Windows is broken regarding Unicode filenames, as described at https://stackoverflow.com/a/4366906/903783

A workaround suggested by user DG there (https://stackoverflow.com/a/13587850/903783) was to use a batch file to accept the dropped file, then pass the filename(s) to the VBScript script file (.vbs) as command-line parameters. If you just care about a single instead of multiple dropped files, there’s a simpler version of a batch file one can use, as I suggested at https://stackoverflow.com/a/52239049/903783. Copying below:


Based on DG’s answer, if you just want to accept one file as drop target then you can write a batch file (if you have it named as "x.bat" place VBscript with filename "x.bat.vbs" at same folder) that just contains:

@"%0.vbs" %1

the @ means to not output the row on the display (I found it to show garbage text even if you use chcp 1250 as first command)

don’t use double-quotes around %1, it won’t work if your VBScript uses logic like the following (code I was using below was from http://jeffkinzer.blogspot.com/2012/06/vbscript-to-convert-excel-to-csv.html). Tested it and it works fine with spaces in the file and folder names:

  Dim strExcelFileName
  strExcelFileName = WScript.Arguments.Item(0) 'file name to parse

  ' get path where script is running
  strScript = WScript.ScriptFullName
  Dim fso
  Set fso = CreateObject ("Scripting.FileSystemObject") 
  strScriptPath = fso.GetAbsolutePathName(strScript & "\..")
  Set fso = Nothing

  ' If the Input file is NOT qualified with a path, default the current path
  LPosition = InStrRev(strExcelFileName, "\")
  if LPosition = 0 Then 'no folder path
    strExcelFileName = strScriptPath & "\" & strExcelFileName
    strScriptPath = strScriptPath & "\"
  else 'there is a folder path, use it for the output folder path also
    strScriptPath = Mid(strExcelFileName, 1, LPosition)
  End If
  ' msgbox LPosition & " - " & strExcelFileName & " - " & strScriptPath

Gotcha: use parentheses around ternary op conditional expressions

Just came across the following case in C# that puzzled me momentarily, especially since the strings involved were long enough and the expression was broken on multiple lines:

bool flag = true;
string test1 = flag? "xa" : "xb";
string test2 = "x" + (flag? "a" : "b");
string test3 = "x" + flag? "a" : "b";

The test3 case fails since the compiler tries to evaluate the "x" + flag expression at the left side of the operator ?, complaining that it cannot implicitly convert string to bool.

e.g I accidentally produced the following wrong code while I was trying to refactor some third-party code to make it more readable:

string test3 = “some long string here” +

                     (someFlag)?

                     “some other long string”

                     :

                     “some alternative long string”;

whereas the correct was:

string test3 = “some long string here” +

                     ( (someFlag)?

                     “some other long string”

                     :

                     “some alternative long string” );

The correct one needs the whole conditional expression enclosed in parentheses. In fact, the parentheses around (someFlag) can be skipped. In usually prefer them visually, even when I use just a boolean variable instead of a more complex boolean expression, but in case like this one the x + (someFlag)? a : b can be confusing to the reader of the code, not seeing x + (someFlag) will be treated as the conditional instead of someFlag.

Luckily the C# compiler is deterministic enough and not trying to imply meaning from one’s wrong syntax. Had it been some futuristic AI-based interpreter, well, it might have gotten confused there too.

To avoid this confusion in the first place, probably one could have designed a (bool)?x:y operator instead with parentheses being required around the boolean expression, but people coming from other languages (say C++) might then end up writing bool && (bool)?x:y and expect the condition to be bool && (bool) instead of just (bool), so even that syntax would be problematic.

Speaking of other languages, quoting from Wikipedia article on ternary operator:

C++

Unlike in C, the precedence of the ?: operator in C++ is the same as that of the assignment operator (= or OP=), and it can return an lvalue. This means that expressions like q ? a : b = c and (q ? a : b) = c are both legal and are parsed differently, the former being equivalent to q ? a : (b = c).

So confusion even between languages that share a C-style syntax might not be avoided.

Fix: Temporary or Local roaming profile message after Windows login

  Researching how to solve a “You have been logged on with a temporary profile” message on a system set up to use a roaming profile (and after I had first checked/fixed the filesystem for errors which is the classic cause for that when using local profiles) I came across this article:

http://www.grouppolicy.biz/2011/07/how-to-reset-a-roaming-profile-in-windows-7

Near the end of the article they mentioned a registry trick from

https://social.technet.microsoft.com/Forums/windows/en-US/5ec0b949-effa-4e30-ba09-dc948a4c7a8b/windows-7-starting-with-a-temporary-profile?forum=w7itprogeneral

So I tried just the registry trick without even logging into an other admin account (it was an admin account that had the problem, although I know people suggest to avoid roaming for those), that is I renamed the account’s profile key under HKLM\Windows NT\Current Version\ProfileList with an appended .bak extension (instead of backing it up externally and then deleting it) and then did log off and log on again.

To find the correct child key to rename, just check each one there and see which one has the ProfileImagePath value for the profile you’re interested in. If for the login you’re using a Microsoft account instead of a local or ActiveDirectory based one and you’re not sure which name it uses underneath, then you can type the text %userprofile% at Search on the taskbar and press ENTER to see which folder path it opens.

  All was then fine on that machine, but then the rest of the computers that were fine before started complaining that due to some problem with loading the roaming profile they loaded a local copy of it instead.

The fix I devised for that issue was to log into those computers with the problematic account, rename the key for the profile again there (adding the .bak extension), log off and log on again, then rename the key back to normal and log off and log on again. That stopped the complaining (simple log off/log on without that renaming wouldn’t fix it).

Στιγμιότυπο οθόνης (4237)

Guess what that did was to not load the roaming profile, but keep referencing it while using the local copy instead and the log off after the renaming of the key to correct value again uploaded the correct profile (from the local copy) to the server.

Note that to open regedit and restore that key’s name after logging in the 2nd time (start menu and taskbar’s search wasn’t working anymore) I had to use CTRL+SHIFT+ESC (was on a remote desktop session) and at the task manager select to see more details, then use its File/Run… menu and give regedit as the command to execute.

Στιγμιότυπο οθόνης (4238)

Στιγμιότυπο οθόνης (4239)

  Btw, I’ve also seen the Reprofiler tool being mentioned, probably it can copy the roaming profile over a local copy or vice-versa if needed – https://iwrconsultancy.co.uk/reprofilerhttps://sourceforge.net/projects/reprofiler/ without having to resort to registry hacks to trick the respective service into copying in the direction one wants.

Categories: Posts Tags: , , , , , ,

Fix: Windows 10 laptops with AMD graphics adapter going really slow

Quoting my comment from a discussion thread on the AMD Community website

Actually the drivers back from 2015 that Microsoft serves for AMD laptop graphics adapters seem to make Windows 10 crawl (at everything, not just in graphics stuff). Installing the newest ones from AMD (in this case the beta driver) makes laptops work decently again.

This doesn’t occur only with the legacy adapters like HD 7310, but also with a bit newer supported adapters like AMD Radeon HD 8600M (have one combined with Intel HD on a Dell Inspiron laptop)

Also note that at every Windows 10 feature upgrade, it seems to replace the newer driver with that older one and then you have to replace it with the newer one again (assuming you had the newer installed before, can do it by right clicking Start menu, selecting to see Device Manager, opening display adapters, right clicking the AMD adapter and selecting Update Driver, then selecting to use one on the computer and then select to pick from list and choose the one with the newest release date or the one with bigger version [those two don’t always seem to be "matching"])

This thing makes both Microsoft and AMD look very bad and wonder when they’ll realize it

So if you have a graphics adapter like AMD Radeon HD 7310 grab the Radeon Software Crimson Edition Beta that contains a beta driver from 2016 (don’t get the WHQL one that comes with the older Catalyst Software Suite or the old one coming from Windows Update) from the AMD legacy drivers page:

https://support.amd.com/en-us/download/desktop/legacy?product=legacy3&os=Windows%2010%20-%2064

And if you have a newer graphics adapter like AMD Radeon HD 8600M that is still supported, get the latest AMD driver using https://support.amd.com/en-us/download/auto-detect-tool

Do not use the old back from 2015 driver that Windows Update installs and make sure you replace it with the newer driver again every time manually after you do a Windows 10 feature upgrade (the periodic major update that Microsoft releases). That is till Microsoft decides to fix this issue and install a performing graphics driver (e.g. have AMD get that legacy driver out of beta) and moreover to not replace your graphics driver with an old problematic one that makes your system crawl to its knees.

%d bloggers like this: