Archive for the 'Web Development' Category


Package and Compress with Google Closure via MSBuild 0

The Problem

So our problem is we are building a library of JavaScript files that we use all over the place. I’ve been pushing, on the project where I’m the sole developer, to wrote 99% of the JavaScript as jQuery plugins. This works great because we can compile that 99% into a single file, or to reverse the perspective, we can split that huge file into smaller, more manageable and logical files.

For example, we have a file called jquery.mycompany.core.js which does a variety of mundane tasks. The file is huge, but unlike C# code, it’s huge for a reason. We want the browser to make as few requests as possible so there is less handshaking, less overhead, and faster page loads.

Previously we had several files and we manually combine them to one and then run it through some online compressing tool once we get close to production. This technically worked, but changes found a way of making their way into the huge file and the segmented files become out of date and obsolete.

The Hack

So here was my plan, take a list of file, concatenate them, and then compress them. Simple enough right? Well, it actually isn’t that bad

  <ItemGroup>
    <JavaScriptFiles  Include="scripts\jQueryPlugins\Custom\core\**\*.js" />
  </ItemGroup>

  <Target Name="Default" DependsOnTargets="BuildAndCompressOrdersJavaScript">

  </Target>

  <Target Name="BuildAndCompressJavaScript">
    <ReadLinesFromFile File="%(JavaScriptFiles.Identity)" >
      <Output
          TaskParameter="Lines"
          ItemName="lines"/>
    </ReadLinesFromFile>

    <WriteLinesToFile File="scripts\jquery.mycompany.core.uncompressed.js"
                      Lines="@(Lines)"
                      Overwrite="true" />

  </Target>

Not so bad right? Lastly, just add a bit of Google Closure. I just shell out and run it from the command line here.

<Exec Command='java -jar ..\compiler.jar --js scpts\jq.myco.core.un.js > scpts\jq.myco.core.js' />

I shortened some paths and filenames there so it would fit better in the blog’s column, but you get the idea.

I threw this into a post build event even though I could have added it to the csproj directly. The post build event was easier and it avoids those nasty warnings when you open the csproj.

The only issue I see with it right now is it is not as portable as I would like it to be. You pretty much company and past the build steps if you need to use it again. This is my major gripe about MSBuild. It’s difficult to create functions you repeat in the build.

This is a total cheapskate way to accomplish this task. I should be creating a nice parameterized MSBuild task, or even better, dump MSBuild for Rake. MSBuild and I acknowledge we are never going to be friends and have come to a professional arrangement. MSBuild does nothing to accommodate me and I do as little as possible with it.

ASP.Net MVC 2.0 RC 2, Input Validation and Breaking Our App 0

It’s been a while since I’ve posted and I’m trying to get back into the swing of things again. I don’t really have a lot to say about the problem, just yet. We’ve identified some breaking changes with ASP.Net MVC 2.0 RC 2.

RC 2 switches to relying on all data annotations on the model when doing validation, when previous releases only checked the values posted and properly bound to a model. To be honest, initially, I didn’t like that idea. It was confusion to me why my model was attributed with attributes requiring fields, but validation was not happening as I expected.

Over time, I came to appreciate, and apparently exploit this feature to do conditional validation. Since the form only posts the enabled controls, I was able to simply enable/disable inputs and doing so, enable/disable their required attribute for model validation.

Everything worked great, until things changed in RC2.

You can read more about the decision to make the switch.

Using iMacros to speed up testing 1

We’ve all had a web application that works in such a way that you are required to complete two or three steps in a workflow to get to the specific page you’re currently developing. It’s a pain to fill out all those required fields, some with complicated regular expression validations (e.g. credit card numbers, e-mail addresses, phone numbers, etc.). It sucks. You have automated acceptance tests, but right now, you’re just exploring with some JavaScript or server code.

So what do you do? What is the normal answer to a boring, repetitious problem. Automate it baby! It’s not that hard at all.  In acceptance testing I’m a big fan of not using the record-and-play type automation. I like seeing the detailed chatter between the browser and the server, but for this throw away situation it’s perfectly fine.

There are two tools that I’ve used to record browser interactions; Selenium IDE and iMacros. Actually, now that I think about it, there are two more; ACT and VSTS Web Tests. I’m going to ignore the last two because I don’t find them very friendly and ill suited for what I’m doing.

Between the two main options, Selenium IDE and iMacros, I use iMacros only because of it’s nicer integration with Firefox. I like the docked sidebar window with all the scripts I’ve recorded as opposed to Selenium IDE’s floating window and needing to load a test suite before being able to run a test. With that said, I do drive all automated acceptance tests with Selenium. The IDE is very useful, the API to interact with the browser has allows all the control I need.  I am very happy with it.

iMacros gives me one button to click to show my scripts.

image

Then a double click takes me where I need to go; simple, fast, efficient.

Recording the scripts are just as easy; click record, use the browser, stop and save.

image

iMacro does have the assertions that Selenium IDE has, but in this scenario, I don’t care. I don’t want to run any assertions, I just want to get where I’m going. iMacros has a few other useful scenarios in our organization:

  • Quick smoke test of problem areas
  • Pre compile pages after deploying website

These two scenarios are probably better served by Selenium and automated through our build server, but it is really simple to setup a script to do whatever you need it to do. Don’t discount it’s power.

Keeping an Eye on Stack Overflow Questions – Taking advantage of RSS 0

It’s probably hard to find a programmer whom hasn’t asked, answered or read a question on Stack Overflow these days. It’s becoming, if not already, the wealthiest pool of talented developers and all those brains are just seething for a challenge. Your problem is another man’s puzzler.

So you’ve asked your question, and now spend every other minute returning to the website to see if anyone has saved your day, or ridiculed your ignorance. Well, there’s an easier way may friends. Even easier than e-mail notifications.

RSS feeds.

it might be easily over looked, but in the bottom of every question there is an RSS feed for that individual question.

image

In fact, there are a couple feeds provided by SO, but for me, today, this one is Queen Bee. Well, this feed and the new Google Reader extension to Google Chrome. Once I get this feed into my Google Reader, all I need to do is wait…

image

…and wait….and stare…and wait….and stare…and wait for the feed icon to update.

image

Sweet. Someone solved my problem. …Nope, just a comment telling me I’m an idiot, but hopefully my rephrased question makes enough sense to get a valid answer.

Feeds make it easy to subscribe to specific information you wish to monitor and lets you do so in a central, e-mail free way. So subscribe until your hearts content, but don’t forget to drop the old questions you no longer care about.

Asp.net MVC 2.0 Data Annotations Validation doesn’t emit correct JSON 1

Apparently I’m not the only one to have this sneaky little problem that has been driving me mad. Given the simple model:

public class Foo {
    [Required] public string Bar {get;set;}
}

And a simple view:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<Foo>" %>
<%@ Import Namespace="MvcApplication2.Models"%>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<script src="/Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcJQueryValidation.js" type="text/javascript"></script>

 <h2>Index</h2>
 <%= Html.ValidationSummary() %>
 <% Html.EnableClientValidation(); %>
 <%
  using (Html.BeginForm())
  {
    ViewContext.FormContext.ClientValidationFunction = "EnableClientValidation"; %>
    <%= Html.LabelFor(x=>x.Bar) %>
    <%= Html.TextBoxFor(x=>x.Bar) %>
    <input type="submit" />
<%  } %>
</asp:Content>

You would expect the form to emit the JSON needed to pass to the jQuery validator right? WRONG! It just outputs the following

<script type="text/javascript">
//<![CDATA[
EnableClientValidation({"Fields":[],"FormId":"form0"}, null);
//]]>
</script>

That’s no help; however, when you give it the <%= Html.ValidationMessageFor(x=>x.Bar) %> you start to see what you expect.

Google Frame to save the day 0

madmen_icon

When they announced Google Frame I was really puzzled. Why? Who would actually want to use IE so badly they would install this? Why not just use the super sexy Chrome and all its goodness?

It finally hit me when today we found a rendering discrepancy on our intranet between IE and the rest of the universe. Ugh! We’re going to hack this thing to get it to work for the three people that want to use IE.

Wait. There is a masked superhero that will save the day. Google Frame!

I have to add one line to my page:

<meta http-equiv="X-UA-Compatible"
         content="chrome=1">

install the plug-in and I’m done! It looks beautiful. The best part is no more sludge and crime in our CSS. Google Frame can clean it all up and prevent any future offenses.

There is no ViewData item of type ‘IEnumerable<SelectListItem>’ that has the key ‘myProperty’. 1

While figuring out the ASP.Net MVC 2.0 Preview 2 Expression HtmlHelpers (that’s a mouthful), I ran into this error a couple times. It didn’t make any sense to me because there shouldn’t be ViewData item with the key “MyProperty” with that type.

It turns out I was doing this:

<%= Html.DropDownListFor(x=>x.MyProperty, Model.AllMyPropertyListItems) %>

It throws this exception when AllMyPropertyListItems is null.

Testing when ModelState is invalid. 0

As a follow up to my previous post, testing when ModelState is relatively simple, but leaves me feelings a little uneasy about my tests.

Here is an example tests, stripped down to remove some of the unnecessary bits

public class When_submitting_lead_data_that_is_in_an_invalid_state : Specification
{
    // class fields...etc

    protected override void Given()
    {
        base.Given();
        _mockOrdersRepository = MockRepository.GenerateStub<IOrdersRepository>();
        _checkoutController = new CheckoutController(_mockOrdersRepository);

        _leadDataWithEmptyPlanName = new PreCheckoutViewData();

        // add an error to the model state
        _checkoutController.ModelState.AddModelError("", "");

        _exceptionWasThrown = false;
    }

    protected override void When()
    {
        base.When();
        try
        {
            _checkoutController.Checkout(_leadDataWithEmptyPlanName);
        } catch(ArgumentNullException)
        {
            _exceptionWasThrown = true;
        }
    }

    [Then] public void an_exception_is_thrown()
    {
        _exceptionWasThrown.ShouldBe(true);
    }
}

This feels pretty loose to me, but there can be another tests that tests which states the model will appear invalid.

ModelState.IsValid is always true 2

We ran into a snag with using the new default Data Annotations Validation in ASP.Net MVC 2.0 Preview 2. Maybe it isn’t a snag, but it is not the behavior I would have expected.

Take the following model:

public class Person
{
  public string ID { get; set; }

  public string FirstName { get; set; }
  public string LastName { get; set; }

  [Required (ErrorMessage = "Required")]
  public string EmailAddress { get; set; }
}

Pretty straight forward, but if you post this form:

    <form action="/person/edit" method="post">
        <input type=hidden name="id" id="id" value="" />
        <input type="text" id="firstname" name="firstname" /> 
        <input type="text" id="lastname" name="lastname" /> 
        <input type="submit" />
    </form> 

To this controller action:

[HttpPost] public virtual ActionResult Edit(Person data)
{
   if (!ModelState.IsValid) throw new ItBrokeException();
   return View();
}

Personally, I would expect every post of that form to show up as invalid, but infact, it is always true. Add the following input to the form and it works.

   <input type="text" id="emailaddress" name="emailaddress" /> <br/>

After that, the ModelState.IsValid returns false, like it should.

Turning Off ASP.Net Validators 2

In true web forms style, what should be simple is more difficult than it should be, at least in my opinion. Today I needed the following simple UI.

image

Simple enough right? Pick something from the list or type your own text. The JavaScript to enable and disable the controls wasn’t too bad. It’s pretty un-interesting, so I’ll just skip over it. What I found surprising was the validators were still firing even though the controls were disabled. I wasn’t expecting it, but oh well. Now to turn off the control’s validators.

I found a lot of examples that looked like the following:

var myVal = document.getElementById('somevalidatorid');
ValidatorEnable(myVal, false); 

That’s nice, but I really don’t want to have to know each and every validator id for each control. It would also make the generic enable/disable code really tightly coupled to the controls we’re trying to disable.

Luckily, we can just find all the validators manually. jQuery can help us out, but isn’t really required.

function enableAllValidatorsFor(control,shouldEnable){
    var validators  = $.grep(Page_Validators,
				function(validator,i){
                                	return validator.controltovalidate == control.id;
                                });
    $.each(validators,  function(i,validator) {
                            ValidatorEnable(validator,shouldEnable);
                        });    

    // the validator callout leaves the error
    // class on the control after the validator gets
    // disabled, so we have to clean that up.
    if(!shouldEnable){
        $(control).removeClass("error");
    }
}        

The last little bit of code removes a CSS class that is set via a validator callout. It is tightly coupled with our pages, so you probably won’t need it, or will need a different class name. However, even though it is tightly coupled, it’s couple to all the pages and not the instance of the control it is disabling. We probably could find the validtor callouts used by the validator controls being disabled and remove any of the error classes they apply, but that didn’t seem necessary right now.

Something else interesting is the inconsistency of the jQuery API in this case. In the “grep” and “each” method the order of the arguments is reversed in the callback.

For grep you have:

function grepCallback(item, index){}

..and for each you have:

function eachCallback(index,item){}

Next Page »