Upgrading AutoMapper

On more than one or two occasions now, I've found myself working with a codebase that uses AutoMapper to perform mapping between objects, most commonly to map data entity objects to their equivalent domain objects.

These codebases often are using a version of AutoMapper prior to version 4.2 which is the version that AutoMapper decided to remove it's static API. I often find the need to upgrade the version of AutoMapper that's in use for any one of a number of different reasons and so I find myself having to re-write all of the AutoMapper initialisation code as the old way of creating mappings is no longer supported.

The problem here is that, in a large enough codebase, moving from purely static mappings as was done with AutoMapper prior to v4.2 to non-static mappings that would need to be either manually constructed or injected into all of the places in the codebase that would require them.  This is often a non-trivial feat and makes moving from static mappings to non-static mappings a much larger job that you might ideally like it to be.

The "proper" way to configure your AutoMaper mappings these days is write code similar to this:

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<SourceObject, DestinationObject>();
});

and then to pass that config object around, or inject it into the class that might need your mapping config.  Of course, if that class is short-lived, you'll need to re-create these mapping configs again and again.  Whilst this is undoubtedly the "best" approach and does not require any static objects, it's sometimes not immediately feasible in an a large, legacy codebase.

There is, however, a way of changing your old, static API-based, mapping configurations in such a way that they continue to use a static object - albeit not the same one as was in AutoMapper < v4.2 - such that the change can be a "drop-in" replacement without having a knock-on ripple effect through out the rest of the codebase.

The Old Way

So the old way of configuring AutoMapper mappings with the static API was something very similar to this:

public class AutomapperConfig
{
	public static void Configure()
	{
		Mapper.CreateMap<SourceObjectA, DestinationObjectA>();
		Mapper.CreateMap<SourceObjectB, DestinationObjectB>();
		Mapper.CreateMap<SourceObjectC, DestinationObjectC>();
	}
}

and the static Configure method would be called within some entry point of your program (i.e. inside the Application_Start method of the Global.asax.cs class)

The New Way

And here's the new way of performing the same thing.  A slight syntactical change to the code and it's a "drop-in" replacement.

public class AutomapperConfig
{
	public static void Configure()
	{
		Mapper.Initialize(cfg =>
		{
			cfg.CreateMap<SourceObjectA, DestinationObjectA>();
			cfg.CreateMap<SourceObjectB, DestinationObjectB>();
			cfg.CreateMap<SourceObjectC, DestinationObjectC>();
		}
	}
}

Note how we use the new Initialize method of the static Mapper object passing in a lambda that performs our mapping configurations rather than constructing a new instance of the MapperConfiguration object to pass to the relevant part of our code that needs to perform mappings.

And with that, we can easily upgrade from AutoMapper pre-v4.2 to a version post-v4.2 without the code changes being too onerous.

KnockoutJS binding on Select elements in a ForEach loop

In an application that I was working on recently, I had the need to bind a select element (i.e. a drop-down list) with KnockoutJS.  This is not an unusual thing to need to do with Knockout, however, this particular select element was ultimately rendered by Knockout itself as it was part of a collection of data objects, and so was within a Knockout foreach binding.

I had a collection of "rates" to choose from in one part of my Knockout View Model and needed to populate another part of the same Knockout View Model with the user's selected rate.  In this case, I wasn't simply selecting the numerical index value or some singular intrinsic data type as the value of the select element, but rather, I needed to whole underlying object.

So, our view model looks something like this:

{
	"MyViewModel" : {
		"Rates" : [{
				"Name" : "Initial Rate",
				"Percentage" : "80",
				"Categories" : [{
						"Id" : "b1fae11b-ce8d-4c72-ad4f-71dc515d0f42",
						"Name" : "Mechanical"
					}, {
						"Id" : "10e01f58-e7f5-4f2c-8d35-e2b87fc43a77",
						"Name" : "Performance"
					}
				]
			}, {
				"Name" : "Extended Rate",
				"Percentage" : "60",
				"Categories" : [{
						"Id" : "10e01f58-e7f5-4f2c-8d35-e2b87fc43a77",
						"Name" : "Performance"
					}, {
						"Id" : "d79a225b-4b76-4371-910d-47a9f3f58665",
						"Name" : "Sync"
					}
				]
			}
		],
		"OverrideRates" : []
	}
}

You can see that we're going to select one of the "Rates" from the array of Rate objects, and that each Rate object doesn't have it's own obvious unique identifier.  Once the user has selected a rate from the rates array, we want to copy the entire object into an OverrideRate object and store that in the OverrideRates array.  Our OverrideRate object will eventually look like this:

{
	"SelectedRate" : {
		"Name" : "Initial Rate",
		"Percentage" : "80",
		"Categories" : [{
				"Id" : "b1fae11b-ce8d-4c72-ad4f-71dc515d0f42",
				"Name" : "Mechanical"
			}, {
				"Id" : "10e01f58-e7f5-4f2c-8d35-e2b87fc43a77",
				"Name" : "Performance"
			}
		]
	},
	"OverridePercentage" : "90",
	"DateFrom" : "2017-01-01T00:00:00.000Z",
	"DateTo" : "2017-12-31T00:00:00.000Z"
}

So you can see here that the entire selected Rate object has been copied from the Rates array into the SelectedRate property.

In order to achieve this, I had markup similar to the following:

<table>
	<tbody data-bind="foreach: MyViewModel.OverrideRates">
		<tr>
			<td>
				<div>
					<select data-bind="options: $root.Rates,
							optionsCaption: 'Please select a rate...',
							optionsText: function(item) {
								return item.Name() + ' (' +
								item.Categories().map(function(elem){ return elem.Name() }).join(', ') + ')'},
							value: $data.SelectedRate">
					</select>
				</div>
			</td>
		</tr>
	</tbody>
</table>

The user was presented with a select element like this:

The Knockout binding for the select element shows that we're telling Knockout to get the options available for selection from the $root.Rates property, which is the collection of available rates (the $root prefix is a special binding context telling Knockout to access the rates object from the root level of the View Model), and further we're telling Knockout to use a special user-defined inline function to take certain string properties of our Rate object and use them to build up the actual text that the user will see inside the select element (i.e. "Initial Rate (Mechanical, Performance)").  Finally, we tell knockout that the "value" of the selected option from the select element needs to be bound to the $data.SelectedRate property.  However, there was a problem.

Two way data binding and data contexts

Knockout's data binding works by having your view model's properties actually be observable functions rather than the data that you actually want to bind.  This means that your MyViewModel.Name property, which can be two-way data-bound to a input box for editing the name string, is actually a function.  The function, when invoked with no parameters (i.e. MyViewModel.Name() ) will return the underlying data - in this case the name string, whilst invoking the function with a parameter (i.e. MyViewModel.Name("Jimmy") ) will set the underlying data to the parameter value passed in.

Whenever Knockout is binding page elements to underlying view model properties inside a loop, you use the special $data binding context prefix in order to access the current object that is currently being processed as part of the the loop.  On all other elements (for example, an input element) this works just fine, since the data that Knockout has to bind is a single value - in the case of a textbox, it's a simple string:

<tbody data-bind="foreach: MyViewModel.Rates">
	<tr>
		<td data-bind="text: $data.Name"></td>
		
	</tr>    
</tbody>

$data gives us a reference to the current rate object within the loop, allowing us to access the Name property of the correct object.  Note that although the Name property of the object is actually a Knockout observable function, we don't need to add the parentheses at the end (i.e. $data.Name() isn't required) since Knockout's binding is clever enough to deal with that for us.

This is great for single, granular pieces of data, however, when attempting to use this binding context as part of my select element that needed not just a simple, singular value, but a whole object to be bound to it, things did work so well.

As the user was selecting a "rate" from the select element drop-down list, I wanted knockout to binding the entire Rate object to the SelectedRate property of the View Model.  This part of the data-bind attribute was intended to achieve that:

value: $data.SelectedRate

However, when examining the View Model with Google Chrome's debugging tools, I noticed that the view model's SelectedRate property was not being updated when the user changed the selection.  Bizarrely, I did notice that when Knockout performed other data binding, for example, when the user changed the value in a textbox that was related to the selected rate, the SelectedRate property was suddenly bound with the correct object!

This was quite strange behaviour, and actually turned out to be a bit of a red herring which was leading my debugging efforts awry.  After much Googling and trial and error, it turned out the issue was all down to observable functions and how they work with the data binding context.

When your $data context isn't

Turns out that when you use the $data binding context in a binding expression, $data is bound not to the Knockout observable function but to the returned value from invoking the function.  This means that $data.SelectedRate was simply returning the underlying values of the observables rather than the observable function's themselves (SelectedRate is also the underlying value since the call to $data is only returning a value, meaning that properties "hanging off" that are also not observables).  This fix is to use a different Knockout binding altogether, which is the $rawData binding context.

Knockout's own documentation describes this:

$rawData

This is the raw view model value in the current context. Usually this will be the same as $data, but if the view model provided to Knockout is wrapped in an observable, $data will be the unwrapped view model, and $rawData will be the observable itself.

 

(Emphasis above is mine).

So, we needed to use the $rawData binding context to ensure that data bound page elements, that are expected to be bound to a complex object, are correctly bound.  And that this is not required when data binding to a simple, intrinsic type (i.e. a string, number etc.)

Interestingly, a Stack Overflow answer to a similar question talks about the $data binding context only referring to the underlying value rather than the observable function, but offers a different solution, one which didn't seem to work correctly for me.

You might think that, since usage of the $rawData binding context is fully explained in the Knockout documentation, why did I not discover and resolve this issue earlier?  Well, it turns out that Knockout has a somewhat chequered history regarding its $data binding context.

Knockout broke my data binding!

Another Stack Overflow question gives us a clue to the history of Knockout's $data binding context.

It would appear that in versions of Knockout prior to Version 3.0, the $data binding context used to function the same as the current version's $rawData binding context works - that is to say that $data used to be bound to the observable function rather than the underlying value. This was entirely due to the fact that the $rawData binding context did not exist in Knockout prior to Version 3.0 and so was considered missing functionality.

With Knockout Version 3.0, the developers introduced the $rawData binding context, however, it was somewhat buggy.  In Knockout Version 3.1, they finally fixed it so that $rawData now correctly refers to the observable function (if one exists) rather than the underlying value, whilst $data continues to "unwrap" the observable and refer to the underlying data value.

Complex custom validation with ASP.NET MVC, jQuery Unobtrusive Validation & KnockoutJS

When developing ASP.NET line of business web applications, one very common requirement is to perform validation of user input.  In a modern, responsive web application this validation is expected to be performed on the client-side, using JavaScript, as well as on the server-side using standard C# code.  ASP.NET MVC ships with jQuery as a standard library and also includes a validation library called jQuery Unobtrusive Validation (latest repository is here), which is an open-source, Microsoft specific add-on to the jQuery Validation plugin.

It's very easy easy to enable jQuery Unobtrusive Validation in an ASP.NET MVC 3+ application.  You simply add the following settings into your web.config:

<configuration>
    <appSettings>
        <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
    </appSettings>
</configuration>

Now, out of the box, jQuery unobtrusive validation allows you to simply decorate your C# model class properties with attributes from the System.ComponentModel.DataAnnotations namespace, like so:

public class MyViewModel
{
	[Required]
	[MaxLength(250)]
	public string Name { get; set; }

	[MaxLength(1000)]
	public string Description { get; set; }
}

Here, we're saying that the Name property is both required and has a maximum length of 250 characters.  The Description property isn't required, but does have a maximum length of 1000 characters if it's supplied.

jQuery Unobtrusive Validation has out-of-the-box implementations of a number of Data Annotation validation attributes, which all derive from the ValidationAttribute class.  Some of these are:

  • Required (ensures the input element is provided and not left empty)
  • MinLength (ensures the text-based input element has a minimum amount of characters entered)
  • MaxLength (ensures the text-based input element has a no more than a maximum amount of characters entered)
  • Range (ensures that the numeric-based input element is within a certain range of values)
  • RegularExpression (ensures that the input elements value conforms to a provided regular expression)

Note that there are more attributes available within the System.ComponentModel.DataAnnotations namespace, however, not all of them have a default implementation within jQuery Unobtrusive Validation.

When the View Model is rendered out to the web page, ASP.NET MVC and jQuery Unobtrusive Validation will render HTML mark-up similar to the following:

<input  id="myField" data-val="true"
		data-val-maxlength="The field Name must not be longer than 250 characters."
		data-val-maxlength-max="250"
		data-val-required="The Name field is required."
		placeholder="Enter Name..." 
		type="text"
		value="">
<span data-valmsg-for="myField" data-valmsg-replace="true"></span>

Here we can see the various data-* attributes being rendered on the input element.  The Unobtrusive Validation JavaScript looks for all elements that are decorated with data-val-* attributes and uses them to perform client-side validation complete with showing/hiding relevant error messages, for example:

Now, this is all well and good when dealing with the most basic of validation requirements, however, there is frequently a need for validation to encompass far more elaborate business rules and complex logic.  Such logic often involves performing certain validation operations not just on a single granular property, but on multiple properties of the model.  It is, unfortunately, at this point that the out-of-the-box jQuery Unobtrusive Validation falls short and we must rely on custom developed validation for this.

Moreover, jQuery Unobtrusive Validation is largely geared towards rendering a web page / form that contains a set amount of input elements when first loaded.  Again, lots of line of business applications frequently have "dynamic" elements added to the form at run-time.  This is most often used when the user of the application is expected to build up a "table" of data, like so:

In the animation above, we can see that new rows are able to be added to the "Rates" table.  We can also see that there's validation on each row of the table, whereby the Owner Writer Share and Net Publisher Share text boxes, which each contain a numeric percentage value, have to add up to 100.

Such user interfaces and forms are not uncommon in a line of business application, but the validation required for this goes way beyond that which the jQuery Unobtrusive Validation offers out of the box.  Developing custom validation for such a form often requires juggling a number of frameworks or libraries and setting up and configuring things "just right" to ensure everything works as expected.  In order to make sense of the various pieces that need to fit together, we'll take a look at each of them one by one.

Creating our custom validator

The first part requires us to create our custom validator.  This requires two steps.  The first step is to create the C# class which is a custom attribute and implements the server-side validation logic, and the second step is to implement a JavaScript function which "mimics" the C# class and provides the same validation logic to the client browser.

Server-side implementation

The C# class is a custom attribute deriving from ValidationAttribute class (for server-side implementation) and also implementing the IClientValidatable interface (in order to "expose" this custom validation logic to the client-side validation framework).   Here's our C# class:

    [AttributeUsage(AttributeTargets.Property)]
    public class MustAddUpToAttribute : ValidationAttribute, IClientValidatable
    {
        public string OtherPropertyName { get; private set; }
        public double Amount { get; private set; }

        public MustAddUpToAttribute(double amount, string otherPropertyName, string errorMessage) : base(errorMessage)
        {
            Amount = amount;
            OtherPropertyName = otherPropertyName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            double thisValue;
            double otherValue;
            PropertyInfo propertyInfo;
            try
            {
                thisValue = Convert.ToDouble(value);
            }
            catch(Exception ex)
            {
                throw new InvalidOperationException("Property Type is not numeric", ex);
            }
            try
            {
                propertyInfo = validationContext.ObjectType.GetProperty(OtherPropertyName);
            }
            catch (ArgumentException ex)
            {
                throw new InvalidOperationException("Other property not found", ex);
            }
            try
            {
                otherValue = Convert.ToDouble(propertyInfo.GetValue(validationContext.ObjectInstance, null));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Other property type is not numeric", ex);
            }
            var sumOfValues = thisValue + otherValue;
            return NumericHelpers.NearlyEqual(sumOfValues, Amount, double.Epsilon) ? ValidationResult.Success : new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessageString, name, OtherPropertyName);
        }
        
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                ValidationType = "mustaddupto"
            };
            rule.ValidationParameters.Add("otherpropertyname", OtherPropertyName);
            rule.ValidationParameters.Add("amount", Amount);
            yield return rule;
        }
    }

(Note that this class relies on a "NumericHelper" to determine near equality - see here for the implementation).

Also note that the .NET Framework provides an IValidateableObject interface, which isn't used here.  The IValidateableObject interface is used for model-level validation - i.e. ensuring an entire object is valid, rather than one or two properties.  Moreover, the IValidateableObject can only be used server-side with no client-side equivalent (client-side model validation must be performed and managed with bespoke JavaScript functions), therefore, it's often unused.

Our C# class takes three constructor parameters, the amount that the calculation must add up to, the name of the "other property" that we'll get the value from to add to the value of the property decorated with the attribute and an optional error message.  The custom attribute is used similar to this:

public class Rate
{
	[Required]
	public float OwnerWriterShare { get; set; }

	[Required]
	[MustAddUpTo(100, "OwnerWriterShare", "Owner Writer Share and Net Publisher Share must add up to 100.")]
	public float NetPublisherShare { get; set; }
}

Note how we use a string based reference to the "OwnerWriterShare" property name to tell the MustAddUpTo attribute that we're getting the value of the NetPublisherShare property (the property to which the attribute is applied) and then to get the value of the OwnerWriterShare property, add them together and determine if the total adds up to the total we require - the first parameter to the MustAddUpTo attribute. Also note that the validation is using both the OwnerWriterShare and NetPublisherShare properties, but the attribute itself is only applied to the NetPublisherShare property.  This ensures we're not "doubling up" by effectively having the same validation on both properties which would result in two copies of the same error message on the client.

So, this C# class gives us our server-side implementation, and includes the GetClientValidationRules method from the IClientValidatable interface.  The implementation of this method requires returning a ModelClientValidationRule object with the relevant properties set.  The ModelClientValidationRule effectively tells the jQuery Unobtrusive Validation framework which client-side implementation it should use along with the relevant parameters required to perform the validation.  We'll see the implementation shortly, but the main code line here is:

ValidationType = "mustaddupto"

The value of ValidationType must always be lower case, and will be the name of our JavaScript function that will implement the client-side validation logic.

Client-side implementation

Having written our C# server-side class, we now must implement the same validation logic on the client-side, which means writing JavaScript.  The JavaScript function name will be mustaddupto.  Here's the JavaScript code that implements our MustAddUpTo validator:

// ================================================================================================
// MustAddUpToAttribute
// ================================================================================================
$.validator.addMethod("mustaddupto", function (value, element, params) {
    // Get the value of the element that the validation is assigned to and
    // the value of the "other" element that we're comparing against.
    var thisValue = value;
    var otherValue = $('#' + params.otherpropertyname).val();
    var amount = params.amount;

    // If either this or the other value is null or "empty" simply return true
    // as we can't perform validation.  Other validation can assert not null/emptiness.
    if (thisValue == null || thisValue.length === 0) {
        return true;
    }
    if (otherValue == null || otherValue.length === 0) {
        return true;
    }

    // Check we're dealing with numbers.
    if ($.isNumeric(value) && $.isNumeric(value)) {
        var thisValueNumber = parseFloat(thisValue);
        var otherValueNumber = parseFloat(otherValue);
        var sumTotal = thisValueNumber + otherValueNumber;
        return nearlyEqual(sumTotal, amount);
    }

    // If we get here, we're dealing with a data type that we don't recognise
    // and can't process, so let the validation pass.
    return true;
});

$.validator.unobtrusive.adapters.add("mustaddupto", ["otherpropertyname", "amount"], function (options) {
    options.rules["mustaddupto"] = options.params;
    options.messages["mustaddupto"] = options.message;
});


// Supporting functions
function nearlyEqual(a, b) {
    if (a == b) return true;
    var diff = Math.abs(a - b);
    if (diff < 4.94065645841247E-320) return true;
    a = Math.abs(a);
    b = Math.abs(b);
    var smallest = (b < a) ? b : a;
    return diff < smallest * 1e-12;
}
// ================================================================================================

The bulk of the function is plain old vanilla JavaScript, but let's examine the first few lines of each block of code in more detail as they're the most interesting parts.  Firstly, we use the addMethod method of the validator object that's attached to the jQuery object in order to create and add our validation method to the jQuery Validation framework.  Note that this isn't the Microsoft-specific jQuery Unobtrusive Validation framework, just the jQuery Validation framework, which is the underlying framework for Microsoft's Unobtrusive Validation framework.  Once we've added our validation method to the jQuery Validation Framework, we'll hook it up to the Unobtrusive Validation library too by adding an "adapter" to the unobtrusive object (this is the line that begins $.validator.unobtrusive.adapters.add).  Firstly, we pass in the name first ("mustaddupto" - this the same name for the ValidationType property of the ModelClientValidationRule that we expose from our server-side implementation) and then a function which takes 3 arguments, value, element and params.  The value parameter is the value of the "property" (or rather element since this is client-side) to which the validation is attached - it's the same as the server-side model property that has the attribute on it.  The element parameter is the actual element that has the validation applied to it.  In our case here, we're only interested in the value itself as the framework will take care of visually highlighting the correct web page element that fails validation, so we don't need to concern ourselves with it here.  What we DO need, though, is the "other" element that we'll need to grab the value of in order to add the two values together.  That's passed in the params object, which is the same object as exposed by the ModelClientValidationRule from the server.  So, the JavaScript params object used in these lines:

var otherValue = $('#' + params.otherpropertyname).val();
var amount = params.amount;

has come from this section of the server-side code:

rule.ValidationParameters.Add("otherpropertyname", OtherPropertyName);
rule.ValidationParameters.Add("amount", Amount);

After having set up and registered our validation function with the jQuery Validation library, we then need to also tell the jQuery Unobtrusive Validation framework all about it's existence too.   We do this with this section of the JavaScript code:

$.validator.unobtrusive.adapters.add("mustaddupto", ["otherpropertyname", "amount"], function (options) {
    options.rules["mustaddupto"] = options.params;
    options.messages["mustaddupto"] = options.message;
});

The jQuery Unobtrusive Validation library has a collection of "adapters" which allow us to register (add) our jQuery Validation method to be used by the unobtrusive validation framework.  Again, we can see that the key parts of this are the name ("mustaddupto") - which is the same as the main JavaScript function name and the name exposed from the server, as well as an array of the string param names ("otherpropertyname" and "amount").

With the C# class written and the attribute applied to our Model class, and the JavaScript function written and registered with both the jQuery Validation and jQuery Unobtrusive Validation libraries, we can move on to the next step...

Adding dynamic elements to the page

In order to dynamically add new elements to a web page without requiring a full page reload, we will be required to use JavaScript or some JavaScript-based framework in order to add elements into the page DOM after the page is initially rendered.  One such framework that actually makes this kind of thing a lot easier to manage is KnockoutJS.  Although it's beyond the scope of this post to go into detail on KnockoutJS, it's sufficient to say that Knockout takes a JSON view model representing your form data and deals with the two-way binding, rendering and updating of both existing and new page elements with the underlying data.  This makes it very easy to dynamically add new elements onto a form, for example, adding new rows to a table of data.

We can expose our server generated viewmodel to the client-side JavaScript with a single line like this:

var koViewModel = ko.mapping.fromJS(@Html.Raw(JsonConvert.SerializeObject(Model)));

The code above uses the Knockout Mapping plugin to take our serialized Model and convert it into a Knockout view model, complete with the required observables to facilitate two-way data binding.  Knockout can then work by "binding" values from the underlying view model to page elements that are decorated with appropriate data-bind attributes, such as this:

<input data-bind="value: MyViewModel.OwnerWriterShare" />

The data-bind attribute tells Knockout to bind the value of the input element to the value of the OwnerWriterShare property of the JSON object, MyViewModel.  This binding is two-way, so changes to the model's value will have Knockout updating the input element, and changes to the input element will have knockout updating the underlying model's value.

This is fine for existing page elements, but Knockout also makes it easy to bind to an array within the underlying JSON model.  This means that as new elements are added to the array, entirely new sets of page elements are created (or destroyed) as the array grows or shrinks.  So, if we have this JSON view model:

{
	"MyViewModel" : {
		"Rates" : [{
				"OwnerWriterShare" : "50",
				"NetPublisherShare" : "50"
			}, {
				"OwnerWriterShare" : "60",
				"NetPublisherShare" : "40"
			}
		]
	}
}

And the following definition of a table within our page markup:

<table>
	<tbody data-bind="foreach: MyViewModel.Rates">
		<tr>
			<td><input data-bind="value: $data.OwnerWriterShare" /></td>
			<td><input data-bind="value: $data.NetPublisherShare" /></td>
		</tr>    
	</tbody>
</table>

Knockout will repeat the contents of the tbody for each element in the MyViewModel.Rates array due to the foreach: binding.  This is great for building up our additional <tr> table rows dynamically, with each element in each row bound to the correct underlying JSON property, managed by KnockoutJS, thanks to the Knockout data-bind attribute.  Allowing users to add a new row to a table is as simple as adding a small amount of JavaScript that simply adds a new element to the underlying view model array, and the Knockout foreach binding will deal with creating the necessary additional page elements.  However, we have further work to do in order to add our validation to the dynamically generated elements, and this involves specifying additional data-* attributes needed for the validation to work, and for that, we'll also require Knockout's help...

Adding validation to dynamically added elements

So, we've got our custom validation functions written and we've wired up Knockout to help generate our page elements and performing the necessary two-way data binding, but now we need to add some additional attributes to our generated markup to ensure that the required validation is added to these elements.

Unobtrusive validation data attributes

Unobtrusive validation works by decorating our elements with data-val-* attributes.  These attributes are ignored by the browser, but JavaScript can read them and the values they contain in order to do all manner of interesting things.  In looking at our rendered input element from earlier:

<input data-bind="value: MyViewModel.Name"
        data-val="true"
        data-val-maxlength="The field Name must not be longer than 250 characters."
        data-val-maxlength-max="250"
        data-val-required="The Name field is required."
        id="MyViewModel_Name"
        name="MyViewModel.Name"
        placeholder="Enter Name..."
        type="text"
        value="">

We can see that as well as the Knockout specific data-bind attribute, we also have a number of attributes the start data-val.  It's these attributes that control the application of validation for the element by the jQuery Unobtrusive Validation library.  There's a data-val attribute that contains a boolean value to indicate whether this element is subject to validation.  Then, we have a number of other attributes starting with data-val that control the actual validation itself.  We'll have an attribute named data-val-VALIDATORNAME for each validation function that is applied to the element, and if that validation required further parameters, these are provided by additional parameters with the required parameter name in the attribute name.  So, for example, the data-val-maxlength attribute contains the error message to be shown when this validation fails and the data-val-maxlength-max attribute holds the value for the maximum length allowed.  We also have a data-val-required attribute that contains the error message for failure of that particular validation, however, there's no further attributes for that validation as no further parameters are required.

Now, when we're rendering known elements from a server-side view model, we can use ASP.NET MVC's Html Helpers to ensure that all of the these necessary attributes are applied to the rendered elements for us, so we will frequently see code such as this in a Razor view:

<div class="form-group">
	@Html.LabelFor(m => m.Username, new { @class = "control-label col-md-3" })
	<div class="col-md-9">
		@Html.TextBoxFor(m => m.Username, new { @class = "form-control", @placeholder = "Enter Username..." })
		@Html.ValidationMessageFor(m => m.Username, string.Empty, new { @class = "text-danger" })
	</div>
</div>

The @Html.TextBoxFor and @Html.ValidationMessageFor directives are aware of any validation attributes applied to the server-side model and will ensure that the relevant data-val attributes are applied to the rendered output (the ValidationMessageFor directive ensuring that the relevant <span> is rendered to hold an validation error message, should validation for the input element fail).

However, since we're now very firmly in the realm of generating our page elements client-side rather than from the server, with the use of KnockoutJS to control dynamically adding elements to the page, we can no longer rely on Html Helpers to write out the necessary elements with the required validation attributes.  Instead, we need to do all of this manually.

Manually adding data validation attributes

So, here's an example of the markup that we'll have to manually write in order to wire up the unobtrusive validation.  We'll examine this in more detail immediately afterwards:

<table>
	<thead>
		<tr>
			<th>Owner Writer Share</th>
			<th>Net Publisher Share</th>
		</tr>
	</thead>
	<tbody data-bind="foreach: MyViewModel.Rates">
		<tr>
			<td>
				<input type="number" min="0" max="100" data-input-type="percentage"
					   data-bind="value: $data.OwnerWriterShare,
							attr: { id: 'MyViewModel_Rates_' + $index() + '__OwnerWriterShare',
							name: 'MyViewModel.Rates[' + $index() + '].OwnerWriterShare' }"
					   data-val="true"
					   data-val-mustaddupto="Owner Writer Share and Net Publisher Share Percentages must add up to 100."
					   data-val-mustaddupto-amount="100"
					   data-val-number="The field Owner Writer Share must be a number."
					   data-val-required="The Owner Writer Share field is required."
					   value="">
			</td>
			<td>
				<input type="number" min="0" max="100" data-input-type="percentage"
					   data-bind="value: $data.NetPublisherShare,
							attr: { id: 'MyViewModel_Rates_' + $index() + '__NetPublisherShare',
							name: 'MyViewModel.Rates[' + $index() + '].NetPublisherShare',
							'data-val-mustaddupto-otherpropertyname': 'MyViewModel_Rates_' + $index() + '__OwnerWriterShare' }"
					   data-val="true"
					   data-val-mustaddupto="Owner Writer Share and Net Publisher Share Percentages must add up to 100."
					   data-val-mustaddupto-amount="100"
					   data-val-number="The field Net Publisher Share must be a number."
					   data-val-required="The Net Publisher Share field is required."
					   value="">
			</td>
		</tr>
	</tbody>
</table>

This markup represents the table that will have rows dynamically added to it at run-time by Knockout and which the two text boxes for our percentages that must both add up to 100.  We can see that many of the data-val-* attributes are simply written out in a hard-coded format (i.e. the data-val, data-val-mustaddupto, data-val-required etc. are all "static" values) and they won't vary from one row of dynamically added elements to the next.  This is all fairly simple so far, however, the Knockout specific data-bind attribute is quite special.

As well as containing the binding to the element's value, we also use the attr binding, which allows Knockout to render attributes on the element.  This is necessary for certain attributes, such as the data-val-mustaddupto-otherpropertyname attribute as this attribute needs to have a value which contains the exact id of the element that we need to examine as part of our validation.  Of course, since we're dealing with potentially many text boxes over many possible rows, these id values need to be dynamically generated and then referenced from the respective data-val-mustaddupto-otherpropertyname attribute.  This is achieved by having Knockout render those attributes for us, as well as rendering our id and name attributes on the element that requires validation.  If we examine the data-bind attributes for each of the <input> elements in the two <td>'s we can see that they both use a Knockout attr binding.  Each of the attr bindings renders both the id and the name of the input element:

attr: { id: 'MyViewModel_Rates_' + $index() + '__OwnerWriterShare', name: 'MyViewModel.Rates[' + $index() + '].OwnerWriterShare' }"

We can see that this binding also uses a special Knockout context property, $index,  which provides the attr binding with the numeric array index of the current data item being processed within the foreach loop.  The resulting markup that's rendered to the page is something similar to this:

<tr>
	<td>
		<input type="number" min="0" max="100" data-input-type="percentage"
			   id="MyViewModel_Rates_0__OwnerWriterShare"
			   name="MyViewModel.Rates[0].OwnerWriterShare"
			   data-val="true"
			   data-val-mustaddupto="Owner Writer Share and Net Publisher Share Percentages must add up to 100."
			   data-val-mustaddupto-amount="100"
			   data-val-number="The field Owner Writer Share must be a number."
			   data-val-required="The Owner Writer Share field is required."
			   value="50">
	</td>
	<td>
		<input type="number" min="0" max="100" data-input-type="percentage"
			   id="MyViewModel_Rates_0__NetPublisherShare"
			   name="MyViewModel.Rates[0].NetPublisherShare"
			   data-val-mustaddupto-otherpropertyname="MyViewModel_Rates_0__OwnerWriterShare"
			   data-val="true"
			   data-val-mustaddupto="Owner Writer Share and Net Publisher Share Percentages must add up to 100."
			   data-val-mustaddupto-amount="100"
			   data-val-number="The field Net Publisher Share must be a number."
			   data-val-required="The Net Publisher Share field is required."
			   value="50">
	</td>
</tr>
<tr>
	<td>
		<input type="number" min="0" max="100" data-input-type="percentage"
			   id="MyViewModel_Rates_1__OwnerWriterShare"
			   name="MyViewModel.Rates[1].OwnerWriterShare"
			   data-val="true"
			   data-val-mustaddupto="Owner Writer Share and Net Publisher Share Percentages must add up to 100."
			   data-val-mustaddupto-amount="100"
			   data-val-number="The field Owner Writer Share must be a number."
			   data-val-required="The Owner Writer Share field is required."
			   value="60">
	</td>
	<td>
		<input type="number" min="0" max="100" data-input-type="percentage"
			   id="MyViewModel_Rates_1__NetPublisherShare"
			   name="MyViewModel.Rates[1].NetPublisherShare"
			   data-val-mustaddupto-otherpropertyname="MyViewModel_Rates_1__OwnerWriterShare"
			   data-val="true"
			   data-val-mustaddupto="Owner Writer Share and Net Publisher Share Percentages must add up to 100."
			   data-val-mustaddupto-amount="100"
			   data-val-number="The field Net Publisher Share must be a number."
			   data-val-required="The Net Publisher Share field is required."
			   value="40">
	</td>
</tr>

Note how the id and name attributes contain the incrementing numeric index, giving each input element a unique id and name.  Furthermore, due to this, the second <td> of each row contains the additional data-val-mustaddupto-otherpropertyname attribute which correctly references that specific row's input element, allowing validation to be wired up to each dynamically added element in each dynamically added table row.

Ensuring validation is performed for dynamically added elements

Once we have Knockout rendering our id, name and validation specific element attributes, we're up and running with our complex validation.  Almost.  There's one final thing that needs to happen in order for the validation to work.  The jQuery Unobtrusive Validation library will initialize it's own internal cache of page elements that require validation when the page has first fully loaded.  Due to this, any page elements that are subsequently added to the page DOM by client-side script (such as our additional table rows, added by KnockoutJS) will not be included in the internal list of page elements that the Unobtrusive Validation will validate.  Therefore, we need a way of telling jQuery Unobtrusive Validation to re-build it's internal list of page elements each time we dynamically add or remove to or from the page any elements containing validation attributes.  This can be done quite simply with a short JavaScript function as follows:

function updateValidation() {
	$("#myForm").removeData("validator");
	$("#myForm").removeData("unobtrusiveValidation");
	$.validator.unobtrusive.parse("#createContract");
}

The #myForm selector represents an id of either a form, or some containing element that encompasses all of the dynamic parts of your web page.  It's important that this function is called by your own JavaScript code whenever a page element is added or removed from the page DOM.  This is usually easy enough to do as adding a table row is usually done in response to the user clicking some kind of "Add" button, which you'll usually have wired up via a Knockout click: binding to run a JavaScript function, usually defined as part of your Knockout view model.  For example, an additional <td> on our table could contain mark up similar to the following:

<td>
	<a href="#" title="Add" data-bind="click: addRateRow">
		<span>Add New Rate</span>
	</a>
</td>

And the addRateRow function would be called on the anchor tag's click event, adding a new row to the underlying Knockout view model - causing Knockout to re-render the table with the additional row and associated elements - and finally calling our simple updateValidation() function to ensure both jQuery Validation and jQuery Unobtrusive Validation are aware of the newly added elements:

koViewModel.addRateRow = function () {
	this.Rates.push(new Rate());
	updateValidation();
};

And with that, our custom complex jQuery Validation / Unobtrusive Validation with KnockoutJS dynamically created page elements is complete!