Team City build no longer including View changes, or published website showing a 404?

One of the websites I develop uses Team City as it’s CI / deployment tool. Up until today, it had successfully (except when it was my fault…) deployed over 200 builds. But today it stopped working.

If, like me, you pre-compile your ASP.NET website (PrecompileBeforePublish) and don’t delete old files (DeleteExistingFiles), you’ll see this problem manifest itself when changes you make to your View files aren’t reflected on your published website (even though they worked fine locally), where-as changes you make to Controllers and other C# files will do.

If you pre-compile your ASP.NET website but do delete old files, you’ll see this problem manifest itself either as above (if you don’t have a Global.asax file) or through your published website displaying 404’s for all your routes, bar those for static assets (CSS, JS, images etc.) if you do.

So, if you’re experiencing the symptoms I describe above, you might want to try disabling your anti-virus and trying again. No, I’m serious. After far too many hours debugging this issue, that was what was causing it for me; specifically, McAfee VirusScan Console’s “On-Access Scanner”. For those of you also screwed over by McAfee, I had to add the following .exe‘s to the list of “Low-Risk Processes”:

  • C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\aspnet_compiler.exe (you may have to swap v4.0.30319 depending on the .NET version you’re using)
  • C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe (you may have to swap v4.0.30319 depending on the .NET version you’re using)
  • C:\TeamCity\buildAgent\plugins\dotnetPlugin\bin\JetBrains.BuildServer.MsBuildBootstrap.exe

Why?

When using PrecompileBeforePublish, Team City copies all files which need to be compiled into C:\TeamCity\buildAgent\work\[workHash]\[buildDir]\obj\[buildProfile]\AspnetCompileMerge\Source. It then invokes aspnet_compiler.exe on that directory, setting the output directory (targetDir in the aspnet_compiler.exe docs) to be ..\TempBuildDir (relative to the previous directory).

In my case, when checking ..\TempBuildDir, I noticed there were no *.compiled files or App_Web_*.dll‘s in the bin folder; the contents of this folder is used as a base for the published website, so none of those files mean no View files in your app! It therefore seems that McAfee blocks them files from being written to disk, for whatever reason.

In summary; disable your anti-virus!

How to dynamically (via AJAX) add new items to a bound list model, in ASP MVC.NET

Imagine you have a form, which allows a user to add n entries. In my case, a user was creating a Building and was defining each Room. Each room had a “Name” and “Area”;

public class Building
{
    [Required]
    public string Name { get; set; }
    public List<Room> Rooms { get; set; }

    public Building()
    {
        Rooms = new List<Room>();
    }
}

public class Room
{
    [Required]
    public string Name { get; set; }
    [Range(1,200)]
    public int Area { get; set; }
}

I had EditorTemplates defined for both Building and Room;

// Views\Building\EditorTemplates\Building.cshtml
@model DynamicListBinding.Models.Building

<div class="form-group">
    @Html.LabelFor(x => x.Name)
    @Html.TextBoxFor(x => x.Name, new { @class = "form-control" })
    @Html.ValidationMessageFor(x => x.Name)
</div>

// Views\Building\EditorTemplates\Room.cshtml
@model DynamicListBinding.Models.Room

<div class="panel panel-default">
    <div class="panel-body">
        <div class="form-group">
            @Html.LabelFor(x => x.Name)
            @Html.TextBoxFor(x => x.Name, new { @class = "form-control" })
            @Html.ValidationMessageFor(x => x.Name)
        </div>

        <div class="form-group">
            @Html.LabelFor(x => x.Area)
            @Html.TextBoxFor(x => x.Area, new { @class = "form-control" })
            @Html.ValidationMessageFor(x => x.Area)
        </div>
    </div>
</div>

… and my Create.cshtml view looked like this;

// Views\Building\Create.cshtml
@model DynamicListBinding.Models.Building
@{
    ViewBag.Title = "Create";
}

@using (Html.BeginForm())
{ 
    <h2>Create</h2>

    <h3>Building</h3>
    @Html.EditorFor(x => x)

    <h3>Rooms</h3>
    @Html.EditorFor(x => x.Rooms)

    <input type="submit" />
}

In fact, you can download the skeleton of this solution from here (or just browse the repository on GitHub here).

Now, I didn’t know how many rooms each building had. My options were:

  1. Give the user an ample amount (say 20) of “Room” entries on the page to start off with, and hope the user wasn’t creating a mansion or castle.
  2. Load additional “Room” entries on-demand using AJAX.

If you’re wanting to use #1, unfortunately you’re in the wrong place, as this article explains how to go about #2. Sorry about that.

What makes #2 hard is how the DefaultModelBinder requires my list of rooms to be named (very specifically), like so;

<input type="text" name="Rooms[0].Name" />
<input type="number" name="Rooms[0].Area" />

<input type="text" name="Rooms[1].Name" />
<input type="number" name="Rooms[1].Area" />

<input type="text" name="Rooms[2].Name" />
<input type="number" name="Rooms[2].Area" />

There are 2 main problems with this:

  1. Imagine I allow my users to delete Rooms as well, and let’s say they delete Rooms[1]. The HTML becomes like so;
    <input type="text" name="Rooms[0].Name" />
    <input type="number" name="Rooms[0].Area" />
    
    <input type="text" name="Rooms[2].Name" />
    <input type="number" name="Rooms[2].Area" />
    

    Because of how DefaultModelBinder works, Room[2], will disappear from my model upon submission, as DefaultModelBinder requires index’s to be consecutive, and stops when it reaches a non-existent index.

  2. When loading additional fields in via AJAX, I need to be able to tell my endpoint what the next index is (because DefaultModelBinder requires index’s to be consecutive).

With these issues in mind, it’s very hard to allow your list of entries to be dynamically added and, potentially, deleted, whilst keeping these indexes sequential.

To make this less hard, Microsoft allow you to provide a .Index field (they just don’t tell anyone this…), which allows you to use any index you want; it doesn’t have to be sequential, and hell, it doesn’t even have to be a number.

We’d then be able to allow our users to delete fields, and the following HTML submission would now work;

<input type="hidden" name="Rooms.Index" value="0" />
<input type="text" name="Rooms[0].Name" />
<input type="number" name="Rooms[0].Area" />

<input type="hidden" name="Rooms.Index" value="2" />
<input type="text" name="Rooms[2].Name" />
<input type="number" name="Rooms[2].Area" />

However, our AJAX endpoint for adding new fields still needs to have some idea which index’s have been used, so it doesn’t generate additional fields with the same name. This approach also introduces the difficulty of using @Html.EditorFor(), whilst being able to output the .Index field.

To save the day, enter a HtmlHelper extension, EditorForMany();

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;

public static class HtmlHelperExtensions
{
    /// <summary>
    /// Generates a GUID-based editor template, rather than the index-based template generated by Html.EditorFor()
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    /// <typeparam name="TValue"></typeparam>
    /// <param name="html"></param>
    /// <param name="propertyExpression">An expression which points to the property on the model you wish to generate the editor for</param>
    /// <param name="indexResolverExpression">An expression which points to the property on the model which holds the GUID index (optional, but required to make Validation* methods to work on post-back)</param>
    /// <param name="includeIndexField">
    /// True if you want this helper to render the hidden &lt;input /&gt; for you (default). False if you do not want this behaviour, and are instead going to call Html.EditorForManyIndexField() within the Editor view. 
    /// The latter behaviour is desired in situations where the Editor is being rendered inside lists or tables, where the &lt;input /&gt; would be invalid.
    /// </param>
    /// <returns>Generated HTML</returns>
    public static MvcHtmlString EditorForMany<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TValue>>> propertyExpression, Expression<Func<TValue, string>> indexResolverExpression = null, bool includeIndexField = true) where TModel : class
    {
        var items = propertyExpression.Compile()(html.ViewData.Model);
        var htmlBuilder = new StringBuilder();
        var htmlFieldName = ExpressionHelper.GetExpressionText(propertyExpression);
        var htmlFieldNameWithPrefix = html.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName);
        Func<TValue, string> indexResolver = null;

        if (indexResolverExpression == null)
        {
            indexResolver = x => null;
        }
        else
        {
            indexResolver = indexResolverExpression.Compile();
        }
                        
        foreach (var item in items)
        {
            var dummy = new { Item = item };
            var guid = indexResolver(item);
            var memberExp = Expression.MakeMemberAccess(Expression.Constant(dummy), dummy.GetType().GetProperty("Item"));
            var singleItemExp = Expression.Lambda<Func<TModel, TValue>>(memberExp, propertyExpression.Parameters);

            if (String.IsNullOrEmpty(guid))
            {
                guid = Guid.NewGuid().ToString();
            }
            else
            {
                guid = html.AttributeEncode(guid);
            }

            if (includeIndexField)
            {
                htmlBuilder.Append(_EditorForManyIndexField<TValue>(htmlFieldNameWithPrefix, guid, indexResolverExpression));
            }

            htmlBuilder.Append(html.EditorFor(singleItemExp, null, String.Format("{0}[{1}]", htmlFieldName, guid)));
        }

        return new MvcHtmlString(htmlBuilder.ToString());
    }

    /// <summary>
    /// Used to manually generate the hidden &lt;input /&gt;. To be used in conjunction with EditorForMany(), when "false" was passed for includeIndexField. 
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    /// <param name="html"></param>
    /// <param name="indexResolverExpression">An expression which points to the property on the model which holds the GUID index (optional, but required to make Validation* methods to work on post-back)</param>
    /// <returns>Generated HTML for hidden &lt;input /&gt;</returns>
    public static MvcHtmlString EditorForManyIndexField<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, string>> indexResolverExpression = null)
    {
        var htmlPrefix = html.ViewData.TemplateInfo.HtmlFieldPrefix;
        var first = htmlPrefix.LastIndexOf('[');
        var last = htmlPrefix.IndexOf(']', first + 1);

        if (first == -1 || last == -1)
        {
            throw new InvalidOperationException("EditorForManyIndexField called when not in a EditorForMany context");
        }

        var htmlFieldNameWithPrefix = htmlPrefix.Substring(0, first);
        var guid = htmlPrefix.Substring(first + 1, last - first - 1);

        return _EditorForManyIndexField<TModel>(htmlFieldNameWithPrefix, guid, indexResolverExpression);
    }
        
    private static MvcHtmlString _EditorForManyIndexField<TModel>(string htmlFieldNameWithPrefix, string guid, Expression<Func<TModel, string>> indexResolverExpression)
    {
        var htmlBuilder = new StringBuilder();
        htmlBuilder.AppendFormat(@"<input type=""hidden"" name=""{0}.Index"" value=""{1}"" />", htmlFieldNameWithPrefix, guid);

        if (indexResolverExpression != null)
        {
            htmlBuilder.AppendFormat(@"<input type=""hidden"" name=""{0}[{1}].{2}"" value=""{1}"" />", htmlFieldNameWithPrefix, guid, ExpressionHelper.GetExpressionText(indexResolverExpression));
        }

        return new MvcHtmlString(htmlBuilder.ToString());
    }
}

Now, I’ll save how this works for another article; all we care about in this one is that it does. To use it, I have to do 2 things;

  1. Add a property to the model, which the EditorForMany helper will store the generated index in. Without this, the Html.Validation* methods will not work (see here for a deep-dive into “why” for the curious).
    public class Room
    {
        [Required]
        public string Name { get; set; }
        [Range(1,200)]
        public int Area { get; set; }
        public string Index { get; set; }
    }
  2. Substitute my Html.EditorFor(x => x.Rooms) in Create.cshtml with:
    @Html.EditorForMany(x => x.Rooms, x => x.Index);
    

… and all of our problems are solved! You’ll see that Html.EditorForMany() uses GUIDs rather than numbers for indexes. This removes the need for us to tell our AJAX endpoint which indexes as been used; as our AJAX endpoint will instead just generate a new GUID. Html.EditorForMany() also takes care of seamlessly producing the .Index field for us as well.

All that’s left to do is to get our AJAX endpoint up and running. To do this, I define a new action on my BuildingController;

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult AddRoom()
{
    var building = new Building();
    building.Rooms.Add(new Room());

    return View(building);
}

… and create a view Views\Building\AddRoom.cshml;

@model DynamicListBinding.Models.Building
@{
    Layout = null;
}

@Html.EditorForMany(x => x.Rooms, x => x.Index)

… and lo-and-behold, after adding the necessary JavaScript to AJAX in a new Room entry at the click of a button (to see what exactly what I changed, see the diff on GitHub), my form now works like a dream.

Note that there is a second way to use Html.EditorForMany(); which is included for scenarios where the hidden <input /> generated by Html.EditorForMany() would be an invalid child of the HTML parent (e.g. within elements such as a <tbody> or <ul>). Here, you’d pass false as the 3rd parameter to Html.EditorForMany(), then within your editor view call Html.EditorForManyIndexField(x => x.Index) to include the hidden <input /> in a valid place in the DOM.

In closing, I’d first like to point you to a blog post on haaked.com, and an answer by DaveMorganTexas on Stack Overflow; which helped me massively on this. I’d also like to thank the people who have commented on this article to highlight issues and improvements which I’ve incorporated over time.

You can browse the GitHub repository of the code used in this article, and download the final code as a zip from here.

Understanding the JavaScript “this” keyword: Part 2

In the previous article, we uncovered the fundamental rules around how the value of this is determined when inside a function. If you haven’t read it yet, head over to the first article, and pop back here when you’re done.

From this point onwards, we’re going to explore a number of JavaScript features that throw those rules out of the window, and allow the caller to choose the value of this.

  1. Changing the value of this using call() and apply()We know if you call someObject.foo() that this inside foo will be someObject. What if we want it to be anotherObject?

    Well, we could do this;

    anotherObject.foo = someObject.foo;
    anotherObject.foo();
    delete anotherObject.foo;

    Bit of a hack, no? Enter call() and apply(). All you have to do is;

    someObject.foo.call(anotherObject);

    What if you want to pass arguments to foo() as well? No problem!

    someObject.foo.call(anotherObject, 1, 2, "abc");

    apply() works exactly the same, but the difference is how they let you pass arguments to the function. call() expects each argument as a separate parameter, whereas apply() expects a single array, whose elements are all the parameters. The equivalent apply() call for the above would be;

    someObject.foo.apply(anotherObject, [1, 2, "abc"]);
  2. Forcing the value of this using bind()bind() is a tricky addition to the JavaScript language (introduced in ES5). If you call someObject.foo.bind(anotherObject), bind() will return a new function; and no matter how you call the returned function (even using call() and apply()), the value of this will always be anotherObject.
    var obj = {
        val: 4
    };
    
    function foo() {
        alert(this.val);
    }
    
    var bar = foo.bind(obj);
    
    foo(); // behaves as expected; alerts `undefined` as `foo` is not attached to an object
    bar(); // breaks the rules! alerts `4` because `bind()` sets `this` to `obj`.
    
    bar.call(window); // this has no effect; still alerts `4`.

    Try it yourself!

    You might wonder how bind() works; but even if ES5 hadn’t included bind(); well, we could roll out our own really easily;

    Function.prototype.ourBind = function(thisArg) {
        var that = this;
    
        return function() {
            return that.apply(thisArg, arguments);
        };
    };

    We could then use ourBind() exactly how we’d use bind(); see it in action on jsFiddle!

  3. The new keyword has the last say…One last feature in JavaScript that I’d like to mention before finishing this article is the new keyword.

    If you’re not quite clued up on the behaviour of new you can read more about it here.

    Using new when calling a function is the final way to change the value of this when calling a function. When you use new, this points to a new object, whose “prototype” is set to the prototype of the function you called new on. Yep; that might take a few reads to sink in.

    The only use case for this is when creating instances of a object; but I just wanted to complete the list of “ways-this-can-be-changed”.

That concludes the articles on this; I hope you now have a much better understanding about how it works! If you want to read a few more articles to help it sink in, I’d recommend this quirksmode article and this Stack Overflow question

Understanding the JavaScript “this” keyword: Part 1

This article is the first of two articles which explain the this keyword in JavaScript. In this first post, we’ll look at what the value of this will be under various invocation scenarios. In the second article, we’ll look at how these rules can be bent by the caller.

Before we begin, I’d like to go over two JavaScript concepts. It’s crucial these are understood to be able to grasp the behaviour of this:

  1. The value of this within a function is not resolved until the function is called.This means that one function can be called 10 different times, and each time a different value of this could be observed.
  2. Whenever you name a function in JavaScript, what you actually do is create a named variable which references that function (i.e. the named variable points to the function). When you assign that named variable to another variable (i.e. alias the function), what you actually do is pass that reference by value, which leaves both variables pointing to the same function.
    // "foo" points to a function which alerts "hi"
    function foo() {
        alert("Hi");  
    }
    
    // Set "b" to point to the same function as "foo" points to (which alerts "hi").
    var b = foo;
    
    // "bar" points to a function which accepts a parameter which points to a function.
    // The body of the function simply executes the function provided.
    function bar(f) {
        f();   
    }
    
    // Pass the function pointed to be "foo" to the function pointed to by "bar".
    bar(foo);

    This means you can have one function, which can be pointed to by multiple variables. If this is still unclear, perhaps the answers to this Stack Overflow question will help the point sink in.

Once you’ve understood the two concepts above, the rules as to what the value of this is is quite straightforward; it’s the rule-bending we discuss in the next article that makes everything more more complicated!

  1. If you access the function via a property of an object, the value of this will be the object.
    var obj = {
        foo: function () {
            alert(this.bar); 
        },    
        bar: 4
    };
    
    obj.foo(); // alerts "4", as `this` inside `foo()` is `obj`.
    
  2. If the variable you access the function from is just a normal variable, the value of this depends on whether you’re in strict mode. Unless you know otherwise, chances are you won’t be.
    • If you are in strict mode, this will be undefined
    • If you aren’t in strict mode, this will the global object. In browsers, the global object is window.
    function foo() {
        "use strict";
        
        alert(typeof this === "undefined");
    }
    
    function bar() {
        alert(typeof this === "object" && this === window);
    }
    
    foo();  // alerts `true`, as inside strict mode, `this` is undefined
    bar();  // alerts `true`, as inside non-strict mode, this is the global (window) object
    

That’s all there is to it! One common “got-cha” however is when you pass a function (which was pointed to by a object member) as a parameter to another function, people still expect this to be the object.

// Define an object which has a property "foo", which points to a function.
// that function alerts "this.val".
var obj = {
    foo: function () {
        alert(this.val);   
    },

    val: "bar"
};

// Remember, if the function we're calling is a member of an object, the value of `this` will be the object.
// In this case "this" resolves to "obj", so we see "bar" being alerted.
obj.foo();

// Lets define another function, which accepts a function as a parameter. All it does is call that function.
function baz(f) {
    f(); 
}

// Now we pass the function pointed to by "obj.foo" to "baz()". "this" will now be the global object, and
// "this.val" will be undefined.
baz(obj.foo);

No! Don’t forget when you alias a function (either by assigning it to another variable or passing it as a parameter to another function), a new pointer to the same function is created. That new pointer has it’s own behaviour; and it’ll follow behaviour #2.

With the rules out of the way, lets go through some examples to see the rules being applied in practise;

function foo() {
    console.log(this);   
}

foo(); // This will be the global object ("window")

var obj = {
    bar: foo  
};

obj.bar(); // This will be "obj"

var baz = obj.bar;

baz(); // This will be the global object ("window") again.

Tracking/ joining parallel AJAX requests with jQuery

When launching a number of AJAX requests simultaneously, it can often be painful to track the requests, and seemingly necessitates the introduction of counter variables to detect when all the AJAX requests have completed. However, since jQuery 1.5, the various AJAX methods have returned a Promise object (an object which exposes only the “safe” methods of a Deferred). This, coupled with the jQuery.when method, allows you to easily add handlers to handle either the successful completion of all AJAX requests, or the failure of one; without the need for you to track anything yourself! To use this approach, simply pass the Promise’s returned by your AJAX calls as arguments to jQuery.when(), then add handlers using the done(), fail() and always() to the Promise returned by jQuery.when(), as demonstrated in the example below.

jQuery.when(jQuery.get('/foo'), jQuery.post('/bar'), jQuery.get('/baz')).done(function (a, b, c) {
    $('#output_a').text(a[0]);
    $('#output_b').text(b[0]);
    $('#output_c').text(c[0]);
});

The ith argument passed to done() is an array of arguments that correspond to the response of the ith Promise passed to when() (i.e. the arguments are available in the order they were provided; the order the responses were received in make no difference). For the example above, this means that a, b and c are all arrays of [ data, textStatus, jqXhr ]. To get the textStatus of the second AJAX call we’d use b[1]. To get the jqXhr object of the 3rd AJAX call we’d use c[2]. All fail() handlers are invoked the first time one of the provided Promises fails. Here however, the arguments are provided as they would be passed into a fail() handler bound directly to the failed AJAX request; i.e. the first argument is the jqXHR object, the second is the textStatus and the third is the error thrown. The behaviour of always() changes depending on whether a request failed or not; if all requests succeed, always() behaves like done(). If a request fails, always() behaves like fail().

jQuery.when(jQuery.get('/foo'), jQuery.post('/bar'), jQuery.get('/baz')).done(function (a, b, c) {
    $('#output_a').text(a[0]);
    $('#output_b').text(b[0]);
    $('#output_c').text(c[0]);
}).fail(function (jqXhr, textStatus, error) {
    alert('A request failed with the error "' + jqXhr.status + '"');
}).always(function () {
    // because of the varying parameter behaviour, its difficult to
    // do anything which uses them.

    $('#loading_spinner ').hide();
});

The signature of jQuery.when() (e.g. having to pass each Promise as a separate argument) can be cumbersome, and make it seem impossible to use when the number of AJAX requests you have cannot be determined. However, we can easily use Function.apply(), and use jQuery.when() using an array of Promise‘s instead;

var ajaxRequests = [jQuery.get('/foo'), jQuery.post('/bar'), jQuery.get('/baz')];

jQuery.when.apply(jQuery, ajaxRequests).done(function () {
    for (var i=0;i<arguments.length;i++) {
        console.log('Response for request #' + (i + 1) + ' is ' + arguments[i][0]);
    }
});

If you have not come across the arguments object yet, you can read about it here. As can be seen in the example above, apply() returns the “master-Deferred” the same way using jQuery.when() directly does, allowing you to bind done(), fail() and always() handlers as before.


For more reading, check out the jQuery documentation for jQuery.when(), or the question on Stack Overflow that triggered me to write this blog post!