Tuesday, May 31, 2016

The res:// Protocol And Phoning Home


An internal tool phones home.

Why does it phone home?

It’s a WPF app that defers most of the heavy lifting to a web app rendered through a Web Browser control.

Initial Approach

Easy enough – clone the website. But where to host it? The tool needs to run without network access.

Second step

Store the contents of the site in the executable itself. It’s a .NET WPF app and this seems like the sort of problem embedded resources were intended to solve.

Unfortunately the WPF web browser control, a light wrapper around IE’s ActiveX control, doesn’t know* how to read from managed resources. It *does* however, know how to read from native/win32/PE resources.

How do we store a native resource in a .NET executable?

.NET executables conform to the PE (Portable Executable) format that all windows executables use. Native resources (native is a retronym in this case, before .NET this was the only kind of resource) are defined as part of the PE spec.

It turns out that Visual Studio automatically creates a native/win32 resource for console projects. This resource stores the icon that the shell uses to represent the executable. And it allows you to specify this file, a compiled resource file (*.res), instead of having it automatically generated.

But how do we get a compiled resource file?

The resource related tooling in Visual Studio for .NET projects assumes use of .NET resources. These are a totally different kettle of fish than native/win32 resources. The MSDN article “About Resource Files” explains how to create compiled resource files (spoiler alert: there’s a resource compiler).

But HTML content assumes a directory structure

Native resources predate the WWW by several years. There’s no support for hierarchically arranged files. There are resource types (e.g., RT_BITMAP, RT_FONT, etc…) but other than resource type the structure is entirely flat. This necessitated some manual mapping/flattening of the HTML.

The cloned website included javascript, css and image content. Most of the image content was due to the ExtJS javascript library. Other than the image content there were very few links: each of these was manually converted to a res:// link.

CSS allows references to resources (e.g., background images) via its URL function. Modern CSS libraries make heavy use of the URL function. It turns out that there were several dozen files referenced this way. Fortunately URL accepts relative and absolute URLs. These were programmatically flattened, included in the compiled resource (.res) file and the referencing URL function updated with the res:// link.

All of the files, including images (*.png), javascript and style sheets, were included in the compiled resource file as type RT_HTML (#23) yielding internal URLs in the form res://MyExecutableName.exe/#23/MappedFileName.ext.

Thursday, October 1, 2015

Web API 2, DateTime and AngularStrap’s DatePickers

Suppose your application uses DateTime objects but only cares about the Date portion. With ASP.NET Web Api 2, building on ASP.NET MVC support, you can take control over how DateTime objects are serialized via c# attributes or configuration.

But suppose you don’t want to change global configuration? In other words, you’d like to change serialization only for a particular page?

My first attempt at this was to use the HttpContent extensibility point by deriving a class specialized for the kind of content (in this case, JsonContent) as described in detail here.

But it struck me that this was overkill since I wasn’t intending to change any of the response headers and only wanted to change a single entry point in the application.

Web API 2 controllers can return an object that implements IHttpActionResult. By implementing this it is possible to control the response body content (json) and thereby control serialization for a specific request. ApiController defines several helper methods that create IHttpActionResult objects for various scenarios (e.g., Ok() returns an OkResult).

The method I needed was Json<T>(). It has an overload that accepts a JsonSerializerSettings object. Setting JsonSerializerSettings.DateFormatString to a pattern that matches the pattern expected on the client side means that the desired DateTime info successfully roundtrips (even through other widgets, in this case, angularStrap’s datepicker).

Tuesday, September 22, 2015

AngularJS: To input type=number or input type=text?

Suppose you have objects that contain numeric properties and these objects are bound to HTML form elements.

HTML5 introduced support for input type=”number” which preserves type fidelity (e.g., object.someProperty starts off as a number in the typeof === ‘number’ sense and remains that way after the user has entered a different number). Preserving type fidelity makes change detection (that is, detecting if the user has changed the model) very simple – angular.equals() can be used directly.

There seem to be two general approaches:

  1. Bind the numeric properties to input type=text form elements then, on save, make sure to cast them back to numeric form (ala parseFloat()).
    1. This tends to complicate the save handler. The data has to be massaged back into numeric form before sending it back to the database.
    2. It also tends to complicate change detection – since the original values from the database are Numbers but angular’s binding does not preserve this type fidelity when bound to input type=text.
    3. It also complicates internal manipulation – e.g., if changing one property requires the recalculation of other properties then this logic will need to account for numbers that get converted into strings via angular binding.
    4. This approach is supported in pretty much every browser.
  2. Bind the numeric properties to input type=number form elements.
    1. This simplifies change detection (angular.equals()).
    2. This simplifies the save handlers.
    3. This simplifies internal manipulation since all manipulators can be certain that they’re dealing with Number variables.
    4. NULL valued numerics are still a problem as these may need to be detected and then defaulted to 0 (or some other numeric default).
    5. Browser support for input type=number is not good.

I would much prefer to take advantage of browser support for numerics and let angular preserve type fidelity throughout model binding. The potential cost of handling NULLs when data is fetched from the database is IMHO small compared to the extra cost of converting back and forth between numbers and strings. Unfortunately, if you have to support any version of IE below 12/Edge then this approach won’t work.

Wednesday, August 19, 2015

Debugging JavaScript With Chrome’s Developer Tools

While going through this chrome developer tools doc to get a better handle on JavaScript debugging in Chrome, I ran across these:

  1. ESC toggles the console drawer.
  2. Chrome’s version of “step over library source” is to provide a way to Blacklist files. e.g., Blacklisting angular.js would prevent the debugger from stepping into angular.js during the debugging session.
  3. Chrome’s version of “first chance exceptions” is to provide a way to pause on caught exceptions (stop sign with a pause symbol on it, don’t forget to check “Pause on Caught Exceptions”).
  4. Right click a breakpoint to make it a conditional breakpoint.

Setting a Breakpoint when the DOM changes

Breakpoints can be set based on when an element’s DOM hierarchy changes, one of its attributes is changed and when the element is removed from the DOM. These breakpoints can be set through the right click menu on an element (Elements pane, element –> right click –>  Break On). These breakpoints show up in the DOM Breakpoints side panel.

Setting a Breakpoint when a JavaScript event is triggered

This can be done from the Sources panel, Event Listener Breakpoints side panel. All supported events are listed in tree form (e.g., mouse –> mouseout for the mouse out event).

Dealing with Minification

Minification, which reduces the amount of data downloaded by the browser, tends to make JavaScript much harder for human debugging. The {} icon at the bottom of the source pane (Sources panel) is the ‘Pretty Print’ button. The Pretty Print button attempts to de-minify the source.

Friday, August 14, 2015

Custom AngularJS Validation With Inline Formatting

Getting a little further along the AngularJS learning curve. Angular has a built in validation framework (including support for async validators!) but to really take advantage of it angular directives need to be created.

The built in validation provides a very convenient way to conditionally display error messages. There's support for minlength, maxlength, regex patterns and several others new in the HTML5 standard.

Given the following snippet of HTML:

1 <div ng-controller="ExampleController">
2 <form name="form" class="css-form" novalidate>
3 Name:
4 <input type="text" ng-model="user.name" name="uName" required="" />
5 <br />
6 <div ng-show="form.$submitted || form.uName.$touched">
7 <div ng-show="form.uName.$error.required">Tell us your name.</div>
8 </div>
10 E-mail:
11 <input type="email" ng-model="user.email" name="uEmail" required="" />
12 <br />
13 <div ng-show="form.$submitted || form.uEmail.$touched">
14 <span ng-show="form.uEmail.$error.required">Tell us your email.</span>
15 <span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
16 </div>
The error messages are conditionally shown based on the built in required and email validators.

I was looking for a way to use something similar, e.g., form.myField.$error.phoneNumber, as the ng-show/if conditional but with application specific validation.

To do this in angular, a directive has to be created. This plunkr demonstrates a custom phoneNumber validator (along with inline formatting, that is, the phone number is normalized upon successful validation). This directive can be applied to a textbox bound to a phone number as folows:

1 <div>
2 Phone Number1:
3 <input
4 type="text"
5 ng-model="phoneNumber1"
6 ng-model-options="{ updateOn: 'blur' }"
7 name="phoneNumber1"
8 minlength="10"
9 maxlength="33"
10 phone-number /><br /> <!-- note: we set maxlength to 33 to allow e.g., 123-456-7890 extension 1234567890 -->
11 <span ng-show="form.phoneNumber1.$error.phoneNumber">The value is not a valid phone number!</span>
12 <span ng-show="form.phoneNumber1.$error.minlength || form.phoneNumber1.$error.maxlength">
13 There must be at least 10 digits in a phone number!</span>
14 </div>

In this snippet the error messages are condtioned on the custom validation supplied $error.phoneNumber. The textbox is decorated with the phone-number attribute which angular uses to apply the validator to this particular field.

Monday, June 22, 2015

AngularJS ng-options: to track by or not

It's been a while but I recently find myself working on a web project using AngularJS. It takes a little while to get the hang of 'thinking' in angular but keeping in mind that it's all about extending HTML makes bridging this conceptual gulf a little easier.

The Single Page Application (SPA) approach makes web development look more like traditional client development in that a lot of state is maintained and manipulated entirely on the client.

One of the core features of Angular is rendering multiple elements of an array (e.g., Orders, Customers, etc...). This can be done with the ng-repeat element or the ng-options attribute to a select list.

With ng-options, if the model backing the selection (the model that stores the currently selected value) is a scalar (e.g., an integral ID, a unique string code, etc...) I've found that using the select as form of ng-options works best. For example, for a dropdown list of customers the model might be a unique customer ID. In this case:

ng-options="customer.customerId as customer.fullName for customer in customers"

allows angular to correctly identify the currently selected customer in the array of customers. This is especially important for models that store previously saved selections.

If, on the other hand, the model is an object (non-scalar), e.g., a customer, then I've found that the label for/track by form of ng-options allows angular to correctly identify the currently selected customer. In this case:

ng-options="customer.fullName for customer in customers track by customer.customerId"

This is handy when the model expects an object for the corresponding property in the underlying Data Transfer Object (DTO).

Tuesday, February 25, 2014

From Startups to MegaCorp: Unlearning to fix everything

In the startup world when you discover an issue, whether it's a logic error or an environmental misconfiguration, being able to fix it quickly and, maybe, document the fix is a virtue.

A hard lesson that I'm learning is that in a different environment that which was a virtue in the startup world can actually be harmful. By fixing an environmental issue you can deprive the organization of the process correction necessary to handle it structurally.

This strikes me as analogous to the decision to *not* handle an error in code. Sometimes you intentionally don't handle an error even though it is anticipated because to do so masks a more fundamental problem. The "if this error occurs, something is deeply wrong in a way that can't be recovered automatically" is a widely established pattern in software construction.

The hard part is realizing that it generalizes to the organizational level. By fixing an environmental issue that another team is responsible for you may well deprive that team of a needed corrective. What happens when you're too busy working on problems that can only be handled by your team and the issue comes up again?