Friday, October 26, 2012

Aliasing Multiple Properties in Knockout JS Bindings

I recently came across another great use for Knockout JS's "with" statement. Traditionally, with is used to limit the binding context to a child class of the view model. However, I recently realized that it's not just limited to the existing view model - you can specify any object in a using directive, even dynamically generated ones.

Which means it's perfect for emulating c# style "using" directives.

 Let me give a (simplistic) example:

<div data-bind="with: {x: longNameItem.LongName, y: longNameItem2.LongName}">
    <div data-bind="text: x.text"></div>
    <div data-bind="text: x.value"></div>
    <div data-bind="text: y.text"></div>
    <div data-bind="text: y.value"></div>
</div>

Additionally, this can help restore sanity when referring to grandparent+ classes:

<div data-bind="with: {parent: $parent, controlRoot: $parents[1], thisForm: $parents[2] }"> </div> 

This allows us to set a readable reference to each level of parent, eliminating $parents[???] mixups.

All this said...

If you are needing to frequently refer to multiple deep children, or frequently refer to great grandparents, you may need to refactor.


Monday, September 10, 2012

Mod_Auth_Tkt, c#, and Blog Posts

(Pete Birkinshaw)

Recently, I was given an opportunity to write a blog post for AIS's corporate blog about mod_auth_tkt.
One of the projects I've been working on recently utilizes the mod_auth_tkt hash method to authenticate between Apache and IIS servers. Along with the blog post, AIS is open-sourcing a c# implementation of mod_auth_tkt, that I had the pleasure of refactoring into an open-source standalone example.

Read more from the AIS blog, or see the newly-released mod_auth_tkt c# source code.

Friday, August 17, 2012

My home workspace


Recently I took the time to clean up my home workspace, so I thought now would be a great time to show it off. Pardon the blurrycam, as photography is not my forte, and these were taken on my 3 year old phone. I may try to update them down the line.

Most of the desk comes from IKEA, including the tan lap desk, which was built from wood in the as-is section. My chair is an Ikea Markus, which is great for tall people. The monitor is a 27" asus @ 1920x1200. I use a Logitech G500 gaming mouse with weights set on the left side to balance out my hand. The keyboard is a cheap but usable Wintec scissor key keyboard, as I hate typing on anything besides scissor keys.

The speakers are from an old stereo with a broken amp, driven by another amp which is best summed up as a college project gone horribly wrong, and a fire hazard waiting to happen.  Yes, it uses a spliced-in ac adapter I found at goodwill and "adjusted". While making it, I also had the experience of browning out a whole dorm building, true story.

On the bookshelf is my media server, which holds 5 1.5 TB hard drives, which serves as the on-site backup (to complement our off-site backup service, SpiderOak) while also hosting a Plex media sever and pyTivo. To switch between the server and assortment of laptops, I use an iogear 4 port KVM, and although it's only VGA, it works great.

The swords/knives are a collection of mine. I have a knife from every continent except Australia and Antarctica (Why haven't those penguins invented tools yet!?!). Specifically, the country list includes Romania, Brazil, India, China, Japan, the C.A.R. (I think), and the good ol USA. Right now you can only see the katana, wakizashi, and tanto sets. Most of the other swords are somewhat scattered around the house.

Any comments appreciated!








Monday, August 6, 2012

Multi-Site Continuous Integration with TeamCity and MSDeploy: Parameters.xml

(JD Hancock)
I love continuous integration. CI servers such as TeamCity let developers see their changes against an example deployment immediately, as well as have a example site for demonstrations. However, what's the best way to CI a project with multiple client builds? For example, a framework project that will be used by multiple clients, each with their own server, database, and asset images?

For that use case, CI makes even more sense. Visual Studio makes it easy to develop on a single build configuration at a time, but would require a host of deployments to test changes side by side. Luckily, TeamCity is great at doing a host of deployments.

The goal for this particular project was to get TeamCity to deploy a solution with four web applications to multiple sites, each of which had it's own set of app settings and specific web.config setup. To do this, we needed to have a way to change these settings, preferably after build. Luckily for us, Microsoft has this functionality built in, though a special file called parameters.xml.

Parameters.xml lets us replace any node in an XML file on deployment. This is similar to web.config transforms, but is customizable for every deployment, can be used for any XML file, and does not require a rebuild. To specify a parameter, follow the format below:

<?xml version="1.0" encoding="utf-8" ?>
<parameters>
  <parameter name="ConnectionString" defaultValue="DefaultSite\ConnectionStrings.config">
    <parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/connectionStrings/@configSource" />
  </parameter>
  ...
</parameters>

Each parameter must have a name and default value. Inside the parameter node, the XML file is specified (scope), along with an XPath location to modify (match). In this example, we have already set up ConfigSource on the connectionStrings in web.config. The parameter will replace the value of ConfigSource with a client specific value.

Along with the parameters.xml file, each site we deploy to will need to have it's own XML file with the specific site settings.

<parameters>
  <setParameter name="ConnectionString" value="Site1\ConnectionStrings.config"/>
  ...
</parameters>

Using MSDeploy is generally straightforward. To deploy these changes to a client site, we will first need to perform a msbuild with a target of "package", and the desired build configuration. We also set the location of the package to a specific location, which will let us find it later on:

msbuild "/path/to/project.csproj" /t:Package /p:Platform=AnyCPU;Configuration=Release;OutputPath=bin;CreatePackageOnPublish=True; PackageLocation=bin\Deploy\project.zip

And in teamcity:



Once the package has been created, we can deploy it to as many sites as we want without having to rebuild. For a quick example, here is a sample msdeploy batch file to use custom parameters when deploying to a local IIS website. The gory details are here, but I'll try to explain the code after giving you a peek :-)

"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package=%1 -setParamFile:%2 -dest:auto -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParam:name="IIS Web Application Name",value="%3"

This batch file takes three parameters: %1 is the zip file package specified in msbuild. %2 would be the client-specific XML file. %3 is the local web site we deploy to. MSDeploy will take the deployment package, inject the parameters into it, and then uploads it to the local IIS instance.

%3 is actually an automatic parameter added when packaging, so we could have added it to the client specific XML as follows:

<parameters>
  <setParameter name="IIS Web Application Name" value="ClientSite1" />
  <setParameter name="ConnectionString" value="Site1\ConnectionStrings.config" />
  ...
</parameters>

However, in this case, I wanted the ability to reuse the deployment package artifacts created by TeamCity. Since the client web sites might have different names then their TeamCity versions, I left it out of the XML. We can use the -setParam command line parameter to set any parameter that is not a constant for each client.

If we run this batch file for each site, we can easily deploy customized releases to multiple IIS applications from a single build:

deploy.bat \path\to\package.zip path\to\site1\variables.xml ClientSite1

deploy.bat \path\to\package.zip path\to\site2\variables.xml ClientSite2

deploy.bat \path\to\package.zip path\to\site3\variables.xml ClientSite3


Monday, July 30, 2012

Running Powershell files from TeamCity

I've come across an amazingly easy way to get past the issue where TeamCity balks at executing powershell scripts. By default, on a brand new server TeamCity will not have access to execute powershell scripts as files, instead throwing an error message such as
zzz cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.
To get around it, the traditional way is to call Set-ExecutionPolicy RemoteSigned, but that can be difficult too, since you need to set it for the same user and architecture (x86 or x64) that TeamCity is running under. Rather then mess with that, Powershell's command line offers a five-second workaround:

-ExecutionPolicy ByPass

In the teamcity powershell build step, just add -ExecutionPolicy ByPass to the command line arguments, and you will be able to execute ps1 files to your heart's content.

Monday, July 16, 2012

Web.Config Tips - File vs ConfigSource

Today I would like to share some things I've learned about two useful attributes in web.config: file and configSource. Both of these attributes are invaluable in setting up modular web sites, because both of them let you break up your web.config file into many pieces. I've looked into both the mono and .Net (through reflector) implementations, to see what makes this tick. Here is a summary of what found:

configSource: ConfigSource is built into all ConfigurationSection elements and simply allows you to move a section to an external file. This works for custom sections too, as long as they inherit ConfigurationSection. When using configSource, unfortunately everything must be specified in the external file. Additionally, this didn't seem to play nice with a <?xml /> header, so just keep that line out.
<mySection configSource="newfile.xml" />
<mySection>
  <item value="1" />
  <item value="2" /> 
</mySection>
file: File is only built specifically into the AppSettingsSection. This is a major bummer, since file lets you specify attributes both in the external file, and in web.config itself. If there are conflicts, the external file always wins. This is great for some scenarios - If you have a external file that is replaced in production or QA phase, this lets you ignore web.config changes and only replace the external file.
<appSettings file="newfile.xml" >
  <add key="first" value="true" />
  <add key="second" value="true" />
</appSettings>
<appSettings>
  <add key="second" value="true" />
  <add key="third" value="true" />
</appSetttings>
Unfortuanely, there are two downsides that I've found with the file attribute. First of all, why is this only present in AppSettingsSection? While it doesn't work for all sections, it would be great for the <connectionStrings /> element, as well as many custom sections.

Secondly, if you want to use web.config transforms to separate debug and release builds, this could provide the opposite behavior from what is desired. For example, say a project kept all of it's app settings in a separate file, but for debug builds, you wanted to change some values of the app config, it would be nice to be able to specify the changed appsettings in the web.debug.config transform.

So what if these aren't enough?

If you are creating a custom ConfigSection, your only built-in option is the wholesale-replacement ConfigSource. If you want to mimic functionality provided by "file" (or even create an external file that is overridden by web.config properties), you have one choice:

Build it yourself.

The easiest way to get started is to have a look at the excellent Mono Project, particualry it's implementation of AppSettingsSection. The key method you should look at is DeserializeElement. Unfortunately, Mono seems to have some significant issues in it's implementation of "file". For one, pathing is broken, at least when I use a standard XmlTextReader insted of the mono specific ConfigXmlTextReader. This can be fixed by looking up the file path manually, probably by parsing out from ElementInformation.Source.

Secondly, base.DeserializeElement will be expecting the reader to be positioned inside the wrapper element, so you may need to do a little extra xml reading to get to the first item inside the wrapper. Beyond that, it's up to you how you want your custom external file process to behave.

I'll leave the final implementation as an exercise to the reader, so have fun with it.

Wednesday, June 27, 2012

IE8 doesn't like to play nice with knockout JS templates

I've come across a bizarre issue with IE8 and knockout JS templates. In a project I'm working on, there is a UL list bound against knockoutJS with a foreach binding:

 <ul data-bind="foreach: choices">
<!-- ko template: {name: $data.template, data: $data} -->
<!-- /ko -->
</ul> 
Inside the template, each list item has a delete button:
<button data-bind="click: $parents[1].deleteMe">x</button>

(Noah Sussman)
This delete button works great. The view model has a deleteMe method on it, that takes the currentItem parram passed in by knockout (see http://knockoutjs.com/documentation/click-binding.html ), and calls choices.remove(currentItem). Query viewModel.choices().length in any browser (even IE 8), and it will correctly return the newer, lesser number of elements.

Unfortunately, it doesn't actually remove the item from the dom in IE8. The template will still show the deleted element, even though the deleted element is removed from the viewmodel.

The only solution I have found so far is, unfortunately, to remove the template tag and stick everything inside the UL. Unfortunately, when using multiple templates inside a loop, this can make for some messy code.

Here's a jsfiddle to test with. In IE8, when deleting an element, notice how the bound .length will decrease, while the elements remain in place. In other browsers, the LI is (correctly) removed.

http://jsfiddle.net/wx78s/

Anyone know of a better way to fix this?

Update:

While this does not solve the problem of templates-inside-a-for-loop, if all you need is a single template, there's an easy workaround.

KnockoutJS templates can include a "foreach" param inside the template itself. This works in IE8, and allows you to iterate over templates in IE8.

Tuesday, June 19, 2012

Chrome's "Print Preview" creates a PDF behind the scenes

While looking at a print preview in chrome recently (v 19 now, I believe), I noticed that the internal html for the print preview dialog simply generates a pdf on the fly. At first, I was hoping this would allow plugin-and-server-free ways of giving a "download as pdf" link, but unfortunately, it's locked down.


Chrome prevents pages from linking to everything under chrome://print, so there's no way for javascript to just call window.print(); window.location.href="chrome://print/zzz.pdf";

In the end, I was hoping there would be an easy way of at least linking to chrome's native "Save as pdf" feature, which may not be easily discoverable by computer novices. With this functionality built in, though, it would be interesting for chrome to make available a way for websites to save a pdf, or open up the print preview dialog with Save as PDF preselected. 

Good idea, or just another nonstandard javascript extension to support?

Tuesday, May 22, 2012

Knockout js - Adding animation for any attribute binding

While documentation can be sparse for KnockoutJS, there still is an easy way to learn about how it works -  by reading the source code. In one of my current projects, I was able to quickly add a custom animation event to knockoutjs even when google was giving me sparse results.

I was working with a knockout-js based image gallery, and i was trying to implement a fade when the user changed images. knockoutjs.com had a basic example of animation here, but unfortunately, it was limited to only two use cases: a foreach loop (which has custom events that no other binding has), or a boolean on-off switch. Even worse, the boolean example puts UI code inside the model. I was hoping to add an animation to a "src" update, or more generally, any attr update.

Since a quick google search was being unhelpful, I switched to look in the knockout js source, particularly for the "attr" binding. Knockout is actually very nice behind-the-scenes, as it uses the same custom-binding syntax for all of it's internal bindings as well. Around line 2484, I found the "attr" binding:

var attrHtmlToJavascriptMap = { 'class': 'className', 'for': 'htmlFor' };
ko.bindingHandlers['attr'] = {
    'update': function(element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()) || {};
        for (var attrName in value) {
            if (typeof attrName == "string") {
                var attrValue = ko.utils.unwrapObservable(value[attrName]);

                // To cover cases like "attr: { checked:someProp }", we want to remove the attribute entirely
                // when someProp is a "no value"-like value (strictly null, false, or undefined)
                // (because the absence of the "checked" attr is how to mark an element as not checked, etc.)
                var toRemove = (attrValue === false) || (attrValue === null) || (attrValue === undefined);
                if (toRemove)
                    element.removeAttribute(attrName);

                // In IE <= 7 and IE8 Quirks Mode, you have to use the Javascript property name instead of the
                // HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior,
                // but instead of figuring out the mode, we'll just set the attribute through the Javascript
                // property for IE <= 8.
                if (ko.utils.ieVersion <= 8 && attrName in attrHtmlToJavascriptMap) {
                    attrName = attrHtmlToJavascriptMap[attrName];
                    if (toRemove)
                        element.removeAttribute(attrName);
                    else
                        element[attrName] = attrValue;
                } else if (!toRemove) {
                    element.setAttribute(attrName, attrValue.toString());
                }
            }
        }
    }
};
BTW, knockout JS is (c) Steven Sanderson - http://knockoutjs.com/
Code is reposted as allowed under the MIT license (http://www.opensource.org/licenses/mit-license.php)

The easy way to add a fade would be to copy this to a custom binding, let's say called "fadeAttr".

ko.bindingHandlers['fadeAttr'] = {

Next, just wrap the for loop in a function, and call it from a traditional jquery fade:

var attrHtmlToJavascriptMap = { 'class': 'className', 'for': 'htmlFor' };
ko.bindingHandlers['fadeAttr'] = {
    'update': function(element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()) || {};
  
  var updateAttr = function (){
   for (var attrName in value) {
    if (typeof attrName == "string") {
     var attrValue = ko.utils.unwrapObservable(value[attrName]);

     // To cover cases like "attr: { checked:someProp }", we want to remove the attribute entirely
     // when someProp is a "no value"-like value (strictly null, false, or undefined)
     // (because the absence of the "checked" attr is how to mark an element as not checked, etc.)
     var toRemove = (attrValue === false) || (attrValue === null) || (attrValue === undefined);
     if (toRemove)
      element.removeAttribute(attrName);

     // In IE <= 7 and IE8 Quirks Mode, you have to use the Javascript property name instead of the
     // HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior,
     // but instead of figuring out the mode, we'll just set the attribute through the Javascript
     // property for IE <= 8.
     if (ko.utils.ieVersion <= 8 && attrName in attrHtmlToJavascriptMap) {
      attrName = attrHtmlToJavascriptMap[attrName];
      if (toRemove)
       element.removeAttribute(attrName);
      else
       element[attrName] = attrValue;
     } else if (!toRemove) {
      element.setAttribute(attrName, attrValue.toString());
     }
    }
   }
  };
  
  if ($(element).is(":visible")){  
   $(element).fadeOut("fast", function (){
    updateAttr();
    $(element).fadeIn("fast");
   });
  }else{
   updateAttr();
  }
    }
};

Now you will have a fade effect whenever you update an attribute. If you wanted to get fancy, you could modify the params to pass in an animation, but I'll leave that as an exercise to the reader. Also, this could get cleaned up significantly if you only change one value, don't set classes, or don't support IE8.

Monday, April 23, 2012

Entity Framework and Saving Objects


I came across a new problem today with entity framework - In one of our projects at AIS, we use a repository to perform data manipulation. We have one function to get the user from the user id, something like:

// first open entities then
return entities.Users.SingleOrDefault(k => k.UserId == userId);

We also have another repository function to save that accepts a user as a param, opens entities, and calls a entities.SaveChanges() on the user. My first reaction was to get the user from the repository, make changes to the needed fields, and then pass the user to the save function.

Unfortunately, Entity Framework did not seem to like saving an existing entity object, and complained loudly, returning:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
It took me a while to find, but the solution seemed to be relatively easy - I just needed to detach the object after the initial selection:

// first open entities then
var result = entities.Users.SingleOrDefault(k => k.UserId == userId);
entities.Detach(result);

return result;

Eventually, this problem may be solved by refactoring the repository to use a single entities object, instead of creating the entity object in each call, but this works for now.

Friday, April 20, 2012

Internet Explorer 7-8 and KnockoutJS

Recently, I've been working on a project that requires IE7 minimum support and KnockoutJS. While Knockout supposedly supports IE6+,  it can be a little rough around the edges when it comes to the archaic Internet Explorers 7 and 8.

Here's a few of the hurdles I've come across so far:

IE 7&8 require quotes around reserved words, such as "class":

<div data-bind="attr: { 'class': cssclass }" >


IE 7 requires you use 'className' instead of 'class':

<div data-bind="attr: { 'class': cssclass, 'className': cssclass }" >


Not knockout specific, but IE7&8 do not support commas at the end of arrays [1,2,3,] - they will add an additional null element to the end of the array.

IE7 does not allow knockout comment bindings in <select> tags

IE7&8 may not support knockout's shorthand tags in some instances:

<div data-bind="..." />


IE7 does not include a native JSON.stringify that is used by ko.toJSON. You will need to include a helper shim.

Friday, April 6, 2012

Rearranging Images in Galleria.io

In one of my current projects, we require an image gallery that is basically sortable. The gallery we settled on, which is actually quite powerful, was galleria.io. Eventually,we ended up with a left and right arrow button under the gallery, which will modify the underlying data. After modifying the data we called .load() on the galleria gallery.

One problem - the gallery would load the new order of images, and then switch to the first image. Easy enough fix - we could just immediately call .show(). Unfortunately this created the problem of "jumping" images - .load would still start on the first image, and then quickly fly over to the current image, every time we reordered.

This seems to be a limitation of galleria.io - loading does not allow us to specify a default start image. Our eventual fix. Unfortunately, was a two line change to galleria.io:

load : function( source, selector, config, index) {

  // Modified by AIS to allow index to be set at load time
  if (index !== undefined) this._options.show = index;

We added a new param, index, to the load function, and set the start image as the index. Not pretty, but it worked. Anyone have a better idea?