Showing posts with label HTML. Show all posts
Showing posts with label HTML. Show all posts

Many to Many Entity Framework 6.0 Relationships Without Extra Nesting

So you've got a many to many (m2m) relationship. And you'd like the Entity Framework to return both ends of this relationship using SQL that isn't overly nested/CASE-d/UnionAll-d.

Let's take the canonical m2m relationship of Authors to Books. An Author can write many Books and a Book can be written by many Authors.

An Author

Many Books
Depending on how well the Entity Framework can figure out the multiplicity of each end you may end up with SQL that's very inefficient.

A human would query this with LEFT OUTER JOINs.

But given the following C# code (LINQ to Entities, query syntax):


from a in AUTHORS
select new { a, a.BOOKS }

The generated SQL has too much nesting and aliasing:

SELECT 
"Project1"."C1" AS "C1", 
"Project1"."AUTHOR_ID" AS "AUTHOR_ID", 
"Project1"."FNAME" AS "FNAME", 
"Project1"."LNAME" AS "LNAME", 
"Project1"."C2" AS "C2", 
"Project1"."BOOK_ID" AS "BOOK_ID", 
"Project1"."NAME" AS "NAME", 
"Project1"."DESCRIPTION" AS "DESCRIPTION"
FROM ( SELECT 
 "Extent1"."AUTHOR_ID" AS "AUTHOR_ID", 
 "Extent1"."FNAME" AS "FNAME", 
 "Extent1"."LNAME" AS "LNAME", 
 1 AS "C1", 
 "Join1"."BOOK_ID1" AS "BOOK_ID", 
 "Join1"."NAME" AS "NAME", 
 "Join1"."DESCRIPTION" AS "DESCRIPTION", 
 CASE WHEN ("Join1"."BOOK_ID2" IS NULL) THEN NULL ELSE 1 END AS "C2"
 FROM  "SCOTT"."AUTHORS" "Extent1"
 LEFT OUTER JOIN  (SELECT "Extent2"."BOOK_ID" AS "BOOK_ID2", "Extent2"."AUTHOR_ID" AS "AUTHOR_ID", "Extent3"."BOOK_ID" AS "BOOK_ID1", "Extent3"."NAME" AS "NAME", "Extent3"."DESCRIPTION" AS "DESCRIPTION"
  FROM  "SCOTT"."AUTHOR_BOOKS" "Extent2"
  INNER JOIN "SCOTT"."BOOKS" "Extent3" ON "Extent3"."BOOK_ID" = "Extent2"."BOOK_ID" ) "Join1" ON "Extent1"."AUTHOR_ID" = "Join1"."AUTHOR_ID"
)  "Project1"
ORDER BY "Project1"."AUTHOR_ID" ASC, "Project1"."C2" ASC

This holds true even if eager loading (.Include("BOOKS")) is used. It would be nice to use a LEFT OUTER JOIN here without the extra nesting.

Modified C# to eliminate nesting:

from a in AUTHORS
from b in a.BOOKS.DefaultIfEmpty()
select new { a, b }

Eliminates the extra level of nesting in the resulting SQL:

SELECT 
1 AS "C1", 
"Extent1"."AUTHOR_ID" AS "AUTHOR_ID", 
"Extent1"."FNAME" AS "FNAME", 
"Extent1"."LNAME" AS "LNAME", 
"Join1"."BOOK_ID1" AS "BOOK_ID", 
"Join1"."NAME" AS "NAME", 
"Join1"."DESCRIPTION" AS "DESCRIPTION"
FROM  "SCOTT"."AUTHORS" "Extent1"
LEFT OUTER JOIN  (SELECT "Extent2"."BOOK_ID" AS "BOOK_ID2", "Extent2"."AUTHOR_ID" AS "AUTHOR_ID", "Extent3"."BOOK_ID" AS "BOOK_ID1", "Extent3"."NAME" AS "NAME", "Extent3"."DESCRIPTION" AS "DESCRIPTION"
 FROM  "SCOTT"."AUTHOR_BOOKS" "Extent2"
 INNER JOIN "SCOTT"."BOOKS" "Extent3" ON "Extent3"."BOOK_ID" = "Extent2"."BOOK_ID" ) "Join1" ON "Extent1"."AUTHOR_ID" = "Join1"."AUTHOR_ID"

This example is based on using Entity Framework 6.0 with Oracle's ODP.NET Managed Entity Framework driver. That driver, in turn, depends on the ODP.NET Managed Framework driver (strangely enough, at least at first glance, these are not the same thing).

Parser-Friendly Angular 1.3.* Formatting

Angular 1.3.* controllers were initially formatted as follows:

1
2
3
angular.module('path.to.moduleName').controller(['$scope', function($scope) {
  //...
}];

This style has its advantages, particularly while learning angular, in that it reinforces the various concepts (modules, app, dependencies) that are important in the design of the framework.

But unfortunately this style tends to stymie many JavaScript parsers. One widely used library for parsing languages is called Ctags. Many editors rely on this library for parsing. And given a sufficiently long controller using the aforementioned format will easily break the parser.

With a small change in formating we can get the benefit of parsers (e.g., Jump To Definition) while working in JavaScript. With such a free-form language I'll take all of the tool help I can get.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
var myCtrlFunc = function() {
    // ... code goes here
    function fun1() {
        //...
    };
    
    $scope.fun2 = function() {
        //...
    };
};

angular.module('path.to.module').controller('myCtrl', [myCtrlFunc]);

Single Page Applications And The Impending Concurrency Explosion

Ok explosion might be a little dramatic but bear with me for a moment.

Going from a Multi Page Application (MPA, did I just coin a retronym?) to a Single Page Application (SPA) is like going from a single synchronization lock (coarse-grained locking) to multiple synchronization locks (fine-grained locking).

Anyone who has made that journey knows that it is fraught with peril. Even for a solo developer it can be difficult to implement without error. For a team of developers, with varying level of application domain familiarity and developer expertise, it is far more daunting.


How is going from an MPA to an SPA like this concurrency problem?

With an MPA the full page submit is analogous to acquiring a single lock. The state of the app is updated in one fell swoop.

With an SPA the same amount of state will be distributed across separate async requests that fire, largely, in response to user interaction. Since the user drives the requests any ordering requirements must be enforced by the developer(s).

Each of these requests is like acquiring one of many locks (e.g., read-only consumers only need the read lock, which is shareable, whereas read-write consumers need both the read and write lock (not shareable)). On the user interface, independently queryable data can update different UI widgets in parallel*. This increases the perceived interactivity of the web app but comes at the cost of increased complexity.

It can be difficult to coordinate multiple lock scenarios even when all of the developers working on the project are co-located. Part of this difficulty stems from the difficulty modeling concurrency - there are many notations available and none used by everyone.

Throw in developers distributed geographically, varying levels of expertise, even varying languages and the coordination required to prevent lock-related errors becomes quite substantial.

The theory of it is sound but in practice there are often subtle data dependencies that don't reveal themselves when all data is fetched and the page is rendered in one fell swoop. That is, the dependencies don't show up until teasing apart the data needed for the various dynamic portions of the page. In other words, the data access patterns of an SPA are going to be different than the data access patterns of an MPA.

Angular And Filtering Exactly

Angular ships with a set of filters for common output transformations (e.g., formatting a date, formatting currency, etc...).

The filter provider also exposes the 'filter' filter. This filter provides a way to query an array of objects based on property values. It's not as sophisticated as LINQ but it's better than nothing.

By default, the filter 'filter' does a substring match instead of an exact match.

For example, the following code snippet:


$filter('filter')([{name: 'one', male: false}, {name: 'two', male: 'trueisms'}, {name: 'three', male: true}], {male: true})

returns a list with 2 objects (male = 'trueisms' and male = true) instead of 1 (which is what I expected). This is because the default filter will return every object with a male property for which true is a substring.

To get exact matching behavior (and thereby return 1 object in the aforementioned example) pass true as the 3rd argument to the $filter('filter')(...) call.


Chrome Tip - Searching Every/All Source Files At Once

To search through every source file loaded by the currently viewed web page (e.g., the HTML, JavaScript and CSS) open Chrome Dev Tools. From the Sources tab right click topmost node in the tree then choose "Search in all files".

Given that it's accessed via an element in a tree one wonders if it can be used to search through all source files under a given node? A quick test confirms this!

Asynchronous Validation In Angular 1.3*

Problem Introduction

One of Angular 1.3*'s more powerful features is its concept of directives. Directives are, in my opinion, what separate Angular from other frameworks and also contributes to its ease of adoption.

If you have worked with HTML at all then you've applied attributes to HTML elements to alter appearance and/or behavior in some way. Why not augment that with the ability to implement custom attributes?

Why Fix This Now?

The need for an application domain specific, server-based auto-complete/type-ahead text input widget crossed an internal, totally subjective threshold of mine. That threshold, N=3, is the point at which I'd like to start consolidating those 3 separate instances into a reusable component because N=4 is rarely far behind N=3 whereas sometimes N=2 is a fluke...

From a framework agnostic perspective this involves providing the user with a textbox for input then, as they type, querying the server and presenting matching options.

How Can Angular Help?

Angular's facility for handling this is its validation pipeline. While it could be done synchronously part of the rationale for an async-heavy framework like Angular is raising the level of interactivity of web applications.

Client side UI frameworks have had support for the behavior for ages (e.g., a ComboBox).

By using the async validation pipeline the user is able to modify other input, resize the browser, etc...  while waiting for results to update. This increases the perceived interactivity of the application.

How Does Angular's Async Validation Work?

Angular's validation framework is exposed through the Form that is published onto $scope by name (e.g., $scope.myForm when the form tag's name attribute is myForm). The details are well described in the Developer Guide/Forms/Custom Validation section.

A Few Considerations To Keep In Mind

  1. Use the custom validation example as your starting point.
  2. The user should be given some indication of progress while the server-side query is executing.
    1. myForm.$pending.myCustomAsyncValidator is defined (e.g., angular.isDefined() returns true) while the operation is executing. Makes an excellent candidate for an ng-show binding.
  3. The promise returned by the custom validator is a little tricky. If the async call succeeds the then-able promise executes any chained callbacks. But it is very likely that you need to inspect the result of the call to determine if the call's input was valid.
    1. To do this, have your custom validator return $q.reject(reason) from the success callback which will trigger rejection.
  4. If validation is failed (e.g., your validator returns $q.reject(reason)) then the error is published to the form property's error object (e.g., myForm.myProperty.$error.myCustomAsyncValidator evaluates to true).
    1. myForm.$valid will also be false.
  5. If validation succeeds (e.g., your validator returns anything other than a rejected promise) then myForm.myProperty.$error.myCustomAsyncValidator evaluates to false.
    1. This doesn't mean that myForm.$valid will be true. All validators (both synchronous and asynchronous) must successfully resolve for myForm.$valid to be true.

Code Snippets


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
angular.module('myModule').directive('myCustomAsyncValidator', ['$q', function($q) {
  //  ... returns a definition object, most omitted for brevity
  return {
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$asyncValidators.myCustomAsyncValidator = function(modelValue, viewValue) {
        
        // ...
        
        // promise executes the server call using viewValue as input, 
        // omitted for brevity
        
        return promise.then(function(data) {
          if (data.failsValidation) { 
            return $q.reject('input not valid');
          } else {
            return angular.copy(data);
          }
        }); // could also handle case where the server call fails to complete here...
      }
    }
  };
}]);

This directive is applied to the HTML input element as follows:

1
<input type="text" name="myProperty" ng-model="data.myModel.myProperty" my-custom-async-validator>


Using ASP.NET Membership with Oracle

So you’ve run the scripts to install the Oracle Providers for ASP.NET. You’ve verified that scripts executed without error. But no matter what you try, the code does not seem to use the OracleMembershipProvider.

The first difference is that the Sql Membership Provider’s root object is Membership while Oracle’s is OracleMembershipProvider.

You’ll quickly notice that the convenience overloads of Membership methods, implemented as extension methods, have not been implemented.

OracleMembershipProvider.CreateUser() - Note that the password question and password answer fields cannot be null (even if they’re not used).

Make sure that the v4 provider dll has been installed into the Global Assembly Cache (via OraProvCfg).

OracleMembershipProvider does not have a static method for constructing new instances (use new OracleMembershipProvider()).

The default constructor does not initialize the object with the settings specified in the application config file. To read those settings call provider.Initialize() with the name you gave the oracle provider in app.config and a non-readonly NameValueCollection containing the membership settings.

But how do we get such a NameValueCollection? Using ConfigurationManager.AppSettings causes an exception indicating that the collection is read-only.

1
2
3
4
5
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);

            NameValueCollection appSettings = ((System.Web.Configuration.MembershipSection)config.GetSection("system.web/membership")).Providers["MyOracleMembershipProvider"].Parameters;

            provider.Initialize("MyOracleMembershipProvider", appSettings);

Using the Visual Studio Diagnostics Hub with an Oracle back-end

Anyone else out there extremely stoked about the Diagnostics Tools that shipped with Visual Studio 2015? The visual display that happens in real-time provides a different kind of coverage than the call-graphs and static call tables you usually get with profiling.
My excitement was somewhat tempered by the lack of support for Oracle/ODP.NET clients. Fortunately, since the Diagnostics Hub is based on IntelliTrace and IntelliTrace is very extensible it is possible to get support for Oracle clients in the Diagnostics and Performance Hub with a few simple steps:
  1. Find CollectionPlan.xml in your Visual Studio installation directory (on my installation it’s in Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\IntelliTrace\14.0.0\en).
  2. Add a module specification for Oracle.DataAccess.dll (<ModuleSpecification Id="oracle.dataaccess">Oracle.DataAccess.dll</ModuleSpecification>)
  3. Add DiagnosticsEventSpecifications as listed below (ildasm helps with this part) then exit and restart Visual Studio for the changes to take effect.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
      <DiagnosticEventSpecification>
        <CategoryId>system.data</CategoryId>
        <SettingsName _locID="settingsName.OracleCommand.ExecuteReader2">ExecuteReader (Oracle)</SettingsName>
        <SettingsDescription _locID="settingsDescription.OracleCommand.ExecuteReader2">Command text was executed, building an OracleDataReader using one of the CommandBehavior values.</SettingsDescription>
        <Bindings>
          <Binding>
            <ModuleSpecificationId>oracle.dataaccess</ModuleSpecificationId>
            <TypeName>Oracle.DataAccess.Client.OracleCommand</TypeName>
            <MethodName>ExecuteDbDataReader</MethodName>
            <MethodId>Oracle.DataAccess.Client.OracleCommand.ExecuteDbDataReader(System.Data.CommandBehavior):System.Data.Common.DbDataReader</MethodId>
            <ShortDescription _locID="shortDescription.OracleCommand.ExecuteReader2">Execute Reader "{0}"</ShortDescription>
            <LongDescription _locID="longDescription.OracleCommand.ExecuteReader2">The command text "{0}" was executed on connection "{1}", building an OracleDataReader using one of the CommandBehavior values.</LongDescription>
            <DataQueries>
              <DataQuery index="0" maxSize="4096" type="String" name="Command Text" _locID="dataquery.OracleCommand.ExecuteReader2.CommandText2" _locAttrData="name" query="m_commandText"></DataQuery>
              <DataQuery index="0" maxSize="256" type="String" name="Connection String" _locID="dataquery.OracleCommand.ExecuteNonQuery.ConnectionString" _locAttrData="name" query="m_connection.m_conString"></DataQuery>              
            </DataQueries>
          </Binding>
        </Bindings>
      </DiagnosticEventSpecification>
      <DiagnosticEventSpecification>
        <CategoryId>system.data</CategoryId>
        <SettingsName _locID="settingsName.OracleCommand.ExecuteNonQuery">ExecuteNonQuery (Oracle)</SettingsName>
        <SettingsDescription _locID="settingsDescription.OracleCommand.ExecuteNonQuery">Command text was executed, returning the number of rows affected.</SettingsDescription>
        <Bindings>
          <Binding>
            <ModuleSpecificationId>oracle.dataaccess</ModuleSpecificationId>
            <TypeName>Oracle.DataAccess.Client.OracleCommand</TypeName>
            <MethodName>ExecuteNonQuery</MethodName>
            <MethodId>Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery():System.Int32</MethodId>
            <ShortDescription _locID="shortDescription.OracleCommand.ExecuteNonQuery">Execute NonQuery "{0}"</ShortDescription>
            <LongDescription _locID="longDescription.OracleCommand.ExecuteNonQuery">The command text "{0}" was executed on connection "{1}", returning the number of rows affected.</LongDescription>
            <DataQueries>
              <DataQuery index="0" maxSize="4096" type="String" name="Command Text" _locID="dataquery.OracleCommand.ExecuteNonQuery.CommandText2" _locAttrData="name" query="m_commandText"></DataQuery>
              <DataQuery index="0" maxSize="256" type="String" name="Connection String" _locID="dataquery.OracleCommand.ExecuteNonQuery.ConnectionString" _locAttrData="name" query="m_connection.m_conString"></DataQuery>
            </DataQueries>
          </Binding>
        </Bindings>
      </DiagnosticEventSpecification>  

The res:// Protocol And Phoning Home

Problem

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.

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 approach 2 which takes 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. [8/2016 EDIT - thank you HTML5 Shim!]

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>
9
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.

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).


Opening a command prompt in a SmartCard security context

In a computing environment with very high security access to many resources requires a physical credential. I’ve only seen this in 2 places: back while working for a bank and at Microsoft. I imagine a similar story in defense related work but I’ve never done defense related contracting so can’t speak from experience.

Anywho, physical credentials are great. Except when you lose them. Or leave them in the computer. Especially if the credential serves double duty; it’s your way to enter the building and to access secured resources.

Windows has a wonderful feature that lets you start a command prompt with the credential. As long as that command prompt remains open it has access to secured resources. So you can take your physical credential out, leave the window open and do what you need to in that command prompt window.

Enter the “runas” command. Introduced in Windows 7 or Vista IIRC, it lets you run a command under different security contexts. One of those contexts is SmartCard. So I created a shortcut on the desktop with the following command:

C:\Windows\System32\runas.exe /smartcard "C:\Windows\System32\cmd.exe /k cd C:\Users\XXX\YYY && C:\Users\XXX\YYY\YYY.cmd"



This opens a command prompt, asks for your credential password then runs the command prompt under the smartcard security context. In this case there’s a bat (.cmd) file that sets up the target command prompt with a bunch of stuff not relevant to this discussion. The /k option to cmd.exe keeps the window open.

Visual Studio Power Tools

If you’re a fan of tools like I am then you’ll appreciate the wonder of the Visual Studio 2010 Productivity Power Tools! They’ve been out for a while but I just got around to installing them. So far I’m loving:

  1. HTML Copy. Now when I copy code from Visual Studio into other applications (like OneNote) the syntax coloring is preserved! Yippee!!
  2. Column Guides. I have mine set at 120 since that’s the recommended line length on my current team. Great to have a visual indicator of this! Just move the cursor to column 120, right click –> Guidelines –> Add Guideline and it’s there.
  3. CTRL+Click to go to definition.

Environment Variables in FOR loops

Let’s say you want to run a program multiple times. The output of each execution should be stored in a separate file to allow for easy comparison. The output filename has useful information so it would be nice to simply append a counter to indicate which run a given output file is associated with. In other words run 1 produces output-1, run 2 produces output-2, …, run N produces output-N.

If you’ve ever tried this using .bat files on windows you might have come up with something along the lines of the following:

@echo off
set f=%1

for /l %%i in (1,1,5) do (
set nf=%f%-%%i

if not exist %nf% (
echo %nf% does not exist
) else (
echo %nf% does exist
)
)


Which surprisingly produces output along the lines of output-5, output-5, output-5, ….



By default the command interpreter CMD only evaluates environment variables (nf in this case) once. To evaluate environment variables more than once it is necessary to enable “delayed environment variable expansion".



This can be enabled when the CMD is started with /v:on. (e.g., cmd /v:on). Alternatively, it can be enabled via setlocal enabledelayedexpansion in an already running CMD prompt.



However, %nf% must replaced with !nf! to get the value of the variable based on the current iteration of the enclosing FOR loop.



So the corrected code is:



@echo off
set f=%1

setlocal enabledelayedexpansion

for /l %%i in (1,1,5) do (
REM set nf=!f!-%%i
set nf=%f%-%%i

if not exist !nf! (
echo !nf! does not exist
) else (
echo !nf! does exist
)
)

endlocal

LINQing away boilerplate collection transformations

Forcing a list of strings to upper case before LINQ:

List<string> list = new List<string> { "element1", "element2", "element3" };
List<string> listCopy = new List<string>();

foreach (string listElement in list)
listCopy.Add(listElement.ToUpper());

foreach (string upperCaseListElement in listCopy)
{
// ...
}






Since LINQ supports transforming sequences inline this can be represented much more succinctly with the following:




foreach (string upperCaseElement in list.Select(el => el.ToUpper()))
{
// ...
}






This expressivity is enabled by C#3.0 support for lambda expressions and the standard query operators.

Yet another reason to love Google Reader

Over the past year or so more and more of the reading I do on the web is being done through Google Reader.

This has been entirely unintentional. It just happens to be very handy to have a single destination that gets updated frequently throughout the day.

Part of this accidental dependence is the result of good design. Google Reader devotes most of its space to the intended content (news, blogs, headlines, etc...).

It makes liberal use of AJAX to make the UI incredibly responsive.

It even has keyboard shortcuts though those haven't grown on me yet.

They've also got several nice bundles of content that make it easy to find interesting articles.

It even plays nice with mobile phones that are not the iPhone. It is hard to overstate how amazing it is that Google Reader works with Pocket Internet Explorer 5! Nothing works with Pocket IE5 except sites that assiduously restrict themselves to whatever meager fraction of WAP-friendly HTML is grokked by Pocket IE5.

Not only does it play nice with Pocket IE5 it even makes other sites play nice with Pocket IE5 by stripping away all of the HTML goodness that PIE5 can't deal with.

I'm not sure I could go back to standing in line without Google Reader on Windows Mobile (or something like it).

Today I discovered that they didn't forget their "raison d'etre". The convenient search bar at the top of the Reader homepage searches, among other things, any of the articles you've ever read in Google Reader! So it's a great way to track down that handy link about something or other you read a while ago but forgot about.

Tables from the Web to the Desktop

Good design tends to spread from wherever it originates to wherever it can be gainfully applied.  HTML tables strike me as an example of this.  Way back in 1996, when the web we know today was but a wee lad, I remember the introduction of browser support for HTML tables.  They instantly became one of many excuses for me to "opt out" of going to class (I was marginally attending the Univ of Penn at the time).  Playing with cellpadding and cellspacing produced visually interesting results (and these turned out to be another instance of good design that were included in tables - control over internal and intra-cell margins) but it became obvious immediately that the big benefit was precise control over layout.

 

Eventually CSS would come to dominate the positioning game but you still find plenty of HTML tables out there on the web. 

 

Anyway, Windows Forms 2.0 introduced the TableLayoutPanel which behaves nearly identically to HTML tables.  Given that the overwhelming majority of display devices (and I include paper as a kind of display device) are 2 dimensional it makes sense that, over time, graphically oriented layout would coalesce around a few "good tricks".  IMHO the best "good tricks" are often rule-based (rule-based in the HTML table sense, not in the CSS 'create as many rules as you like' sense).  I'm a fan of CSS - it provided a much needed solutions to many design (and management) problems but that's a post for another day.

 

It is good to see good design migrating from one modality (the web) to another (the smart client/desktop/OS).

HTML Help for Windows Forms

I briefly tried using HTML Help Workshop to provide context sensitive help for a Windows Forms application but had no luck. Recently I've gotten a chance to take another look at it. So here are a few tips:


  1. Create a separate HTML page for each topic.

    • Another way to put this is to create a separate HTML page for everything that might require context sensitive help. E.g., every user interface widget (or at least those you want to provide with context sensitive help).
    • Use whatever HTML editor you prefer - I like the Visual Studio 2005 designer so I use that.

  2. Create an HTML Help project (.hhp) in the directory containing the HTML files.
  3. Manually add all of the HTML files to the project.
  4. Don't bother with automatically generating a table of contents since all sections within a file will link to the top of the file.
  5. Manually create a Table of Contents from the "Contents" tab.

    • There are 2 types of entries; headings and pages.
    • Heading entries are represented by a book and can contain child entries.
    • If you want the heading entry to display a topic (=HTML page) when clicked you have to edit it.
    • Edit an entry by selecting it then clicking the pencil button to open the "Table of Contents Entry" editor.
    • Under "Files/URLs and their information types" add the topic (e.g., MyFirstTopic.html) to the list.
    • Do the same thing for pages since you usually want a topic to display when a page is clicked from the TOC.

  6. Use relative Files/URLs so that moving the project and its html files to a different directory won't prevent compilation.
  7. Compile the project then click the glasses icon to view the .chm file.

Once the HTML help project is done compiling a new .CHM file can be automated in a post-build event that uses the HHC.exe in the program files directory for HTML Help Workshop.