Tuesday, July 12, 2016

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

Wednesday, June 1, 2016

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 DiagnosticsEventSpecification as listed below 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
<DiagnosticEventSpecification>
  <CategoryId>system.data</CategoryId>
  <SettingsName _locID="settingsName.OracleCommand.ExecuteReader2">ExecuteReader (Oracle)</SettingsName>
  <SettingsDescription _locID="settingsDescription.OracleCommand.ExecuteReader2">Command text was executed, building an Oracle 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, building an OdbcDataReader using one of the CommandBehavior values.</LongDescription>
      <DataQueries>

        <DataQuery index="0" maxSize="4096" type="String" name="Command Text" _locID="dataquery.OdbcCommand.ExecuteScalar.CommandText2" _locAttrData="name" query="m_commandText"></DataQuery>
      </DataQueries>
    </Binding>
  </Bindings>
</DiagnosticEventSpecification>

Tuesday, May 31, 2016

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.

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