Today’s post explains a user interface that is not uncommon. The user interface consists of a list of items, and if the user clicks a link in the row of data for an item, a dialog window appears so the user can edit the details of the item. When the user saves their changes, the table updates itself to reflect the new changes.

I’m going to cover an approach you can use with ASP.Net MVC to enable this, and explain the aspects required for the Controller and Views that make it all hang together. I’m not going into detail about where the data comes from or what the data is. The idea here is to concentrate on the pattern – you can work out what the data for the list and details screens, respectively, is.

Controller

We’ll set up the controller first. The controller requires at least four methods:

Index method

This handles the initial interaction of the user with the screen. It’s job is to retrieve the data from whatever is the data source to display and display the “Index” View.

The Record – Get – Method

This action returns a partial view via Ajax of the record to be edited. I will cover in a moment what is done on the client, but this method builds the edit View Model for the entity by first retrieving it from the data store. Note the use of the null able parameter to indicate if a new record should be created.

Also of interest is the use of the OutputCache action filter to ensure that the Ajax GET request is not cached on the client.

The Record – Post- Method

This method does the update based on a POSTed model. Note how it the method has same name as the previous method, but is decorated with a [HttpPost] attribute and takes a populated entity model as a parameter. If the ModelState is valid, then it is prudent to clear the model state so that posted values are not re-displayed when rendering the view. Instead, the model is refreshed from the data store.

The partial list refresh

Once the record has been updated, the list of records needs to refresh itself. To do this, it need to make an Ajax call to the server to return a PartialView of just the table contents. That’s what this method does. Note again the use of the [OutputCache] filter to prevent Ajax request caching.

Views

Okay, so that’s the controller covered, now lets consider the views. I’m going to use 3 views:

Index – the initial view when the user goes to the list.

Detail – the details view of the entity, used for creates and edits.

List – the partical view of the table of entitites.

The Index View

This is very simple. It simply renders the partial list view and all the client side script that makes it all work. Aside from the comments in the script, the keys points are the hidden div for the placements of the Ajax retrieved content.

@model MyListModel
@{
ViewBag.Title = "List of Entities";
Layout = "~/Views/Shared/_MainLayout.cshtml";
//render the partial view
Html.RenderPartial("List", Model);
}
<!-- container for ajax loaded dialog content -->
<div id="ajax-content" style="display:none">
</div>
<script type="text/javascript">
//<![CDATA[
//this function gets called when the ajax request to GET a entity detail has completed.
//The GET request ends with the returned HTML being placed in the div with id='ajax-content'
//A modal dialog is created. The title for the dialog is extracted from the contained fieldset legend.
//On close, the dialog is destroyed and the content of the ajax-content div are removed
//On Save the contained form is submitted
function loadEntity(xhr, status) {
$('#ajax-content').dialog({
modal: true,
width:600,
title: $('#ajax-content legend').text(),
buttons: {
"Save": function () {
//submit the form
$('#ajax-content form').submit();
},
"Close": function () {
//remove the content, destroy the dialog
$(this).dialog('destroy').html('');
}
}
});
}
//this function gets called when the contained form has been submitted via ajax
//this results in the content INSIDE the ajax-content being replaced, however ajax-content, which is wrapped in
//a dialog, is not replaced and so remain visible.
//The title of the dialog is refreshed based on the contained legend.
//The last thing this function does is makes the table 'entity-list' reload itself from the appropriate Url which points to the "EntityList" action on the controller
function entityDetailsUpdated(responseText, status, xhr) {
$('#ajax-content').dialog("option", "title", $('#ajax-content legend').text());
$('#entity-list').load( '@Url.Action("EntityList")');
}
//]]>
</script>

The List View

This is simply a table that shows whatever properties of the entity you want, but with one of the properties being rendered as an Ajax.ActionLink. This little Microsoft extension simply leverages the jQuery Ajax stack in an unobtrusive way. You can see that I have used the AjaxOptions class to define that callback function to call when the Ajax call is complete and the element to put the returned content in, both of which are defined in the Index View.

Note the use of the additional link in the footer of the table to create a new record. In this case, no id is passed to the controller.

Conclusion

This post has demonstrated how to achieve the user interface pattern for master-Details views with dialogs using ASP.Net MVC, jQuery and unobtrusive Ajax. The same effects can be created using explicit script of course, but the unobtrusive Ajax extensions are a time saver and make your views more succinct.

In razor, there is no access to the ClientScriptManager so there is no readily available method of using that class’s useful GetWebResourceUrl method to retrieve embedded resources. There are few techniques for synthesizing the functionality, revolving around the reflection of the AssemblyResourceLoader class which is all fine and well unless the application trust level prohibits reflection of non-public members. A simpler and pragmatic method is to have a partial view of the old ascx variety, and have it access the ClientScript manager of it’s Page property as below:

Introduction

It is a somewhat inconvenient truth that users of your web site are everywhere but they don’t all talk the same language or even do simple things like read dates in the same way. ASP.Net prov ides rich support for globalization. This post covers the localization of dates, the different treatment ASP.Net applies to dates received in a QueryString to those in posted fields and provides some techniques to mitigate any issues caused by this different treatment.

ASP.Net treats Dates in URL’s different to POST fields

This came as a surprise to me. When ASP.MVC binds values from POSTed fields, it applies the current culture, but when it binds values from the URL (querystring) is uses the Invariant Culture.

This can result in unpleasant effects, particularly if like me (programming in Australia) want dates in the format day-month-year, and not the invariant month-day-year.

Say you had a form with a input field for dates. If the user entered ‘14/5/2011’ and the form was submitted via GET instead of POST, MVC would complain that this was not a valid date. If you submit the form via POST, MVC would bind the date correctly.

I wrote to Phil Haack about this:

Hi Phil,I noticed this one today. I’m in Australia (en-AU), so it common to use dates of the form dd/mm/yyyy.When these fields are POSTed, the values are as expected, because the ValueProviderResult is being constructed with the CurrentCulture out of the Mvc.FormCollection.But when the string is submitted via GET, the NameValueProvider is creating a ValueProviderResult with the Invariant culture, which is different to the current culture, and it doesn’t believe that 29/4/2011 is a valid date (29 April 2011). Most upsetting !

He replied thus

Yeah. We made a conscious choice that values pulled from the URL would be culture invariant. The reason is that URLs must be uniform. So if I send you the URL, it shouldn’t change its meaning whether the person clicking it is in AU or in US.

I can’t say I’m convinced as to his reasoning. It kind of assumes that URL’s are static and only accessed by ‘clicking’. But a form submitted via GET is a totally different interaction to a mere click. This logic more or less requires unless the server current culture somewhat reflects the invariant culture (ie you’re in the US) you should POST your forms. Consider the following simple page:

Assuming that using a cultre with a date format dd/MM/yyyy, if you fire up this page and enter a date of say ’14/5/2010′, you will get an error from the server:”The value ’14/5/2010′ is not valid for SubmissionDate”. Not ideal!! This is a bit of a restriction but there is a workaround. You need to hook into the form submit event, get the URL the form was going to send, including it’s serialized field information and manually find and replace date fields with their equivalent invariant values. Then manually submit the form and cancel the default event. This is done using the script below:

If you run this and submit, then the date will be parsed correctly. However a problem exists – when the date is displayed to the user, it is in the format posted to the server, so although the user typed dd/MM/yyyy, MVC saw yyyy/MM/dd in the query string and this is the format returned to the user. To get around this, you need to ensure that the users local or preferred culture is automatically set from the user’s browser by setting the following web.config element:

This will result in output to the browser of, for example, dd/MM/yyyy for en-AU, MM/dd/yyyy for en-US and YYYY/MM/dd for ja-JP.

The problem still remains in that I want the date to come back to the browser in an invariant manner, so I’m going to modify my submit script to take into the current culture and always submit the date in yyyy/mm/dd format – ISO-8601 format. But because the relative positions of date, months and years can change between cultures, I need to work out the positions before applying the respective replacement regex. To do this, I create a test date and format it to a string in the current UI Culture and test what the first element is. That tells me whether the date or month or year comes first. I can then render the appropriate regex accordingly.So instead of:

I need to use some Razor C# when rendering the script block as follows:

....//following on previous script
@{
//create a known date
string testDate = new DateTime(2000, 10, 30).ToString("d");
//replace the known values for years, months and days
//with the replacement regex expressions
string dateRegex = testDate.Replace("2000", @"(\d{4})")
.Replace("10", @"(\d{1,2})").Replace("30", @"(\d{1,2})").Replace("/", "%2F");
//see if the produced date starts with the date component
if(testDate.StartsWith("30")){
@:data = data.replace(/@dateRegex/g, "$3%2F$2%2F$1");
}
//see if it starts with the month component
else if(testDate.StartsWith("10")){
@:data = data.replace(/@dateRegex/g, "$3%2F$1%2F$2");
}
//it starts with the year component so no work to be done
}
....//continuing on with the script

Obviously you can extend the logic to test for date culture formats such as yyyy/dd/MM or dd/yyyy/MM (if such cultures exist) but I hope you get the point.

Localization and jQuery datepicker

It is worth noting how to switch the jquery datepicker localization. It’s simply a matter of dynamically setting the localization js as follows:

Introduction

In a previous post I covered the use of Custom Unobrusive Validation in ASP.Net MVC using the IClientValidatable. The use of this interface may not always be possible, for example if the validation attribute is defined in an assembly that cannot reference the MVC assembly, or such a reference makes no sense. Under these circumstances, there is another approach to take and that is to use adapters to help the MVC assign the client side validation to apply for a given validation attribute.

Server side code

I’ll use the same example as last time, that is a check sum validator for Australian Business and Company Numbers, but in this case I will not be implementing IClientValidatable.

Without the IClientValidatble interface, we need to create a “buddy” class of type DataAnnotationsModelValidator<TValidationAttribute> that MVC will use to create the data-val information for a given validator.

Of course, my caveats about placing this script after the dependant javascript libraries have been loaded still apply.

Conclusion

This post have demonstrated how to use Custom Unobstrusive Jquery Validation in ASP.Net MVC 3 using DataAnnotationsModelValidatorProvider instead of IClientValidatable. This is a suitable solution where it is not possible to decorate an attribute the the IClientValidatable interface or it is inappropriate to reference the MVC library from the assembly the validation attribute is defined in.

Introduction

Understanding scopes

In common with most languages, JavaScript has the concept of scope. Scope defines what objects are visible to a body of code at runtime. In JavaScript script the variables in scope are those in scope at the time the function was created or assigned. Variables defined in the global scope are visible to all code so long as the variable or object has been declared prior to the code in question:

JavaScript code is run in the context of a call object, which contains references to all accessible variables. Each new function or frame results in a new call object being chained onto the previous (parent) one, with the properties of the parent scope being available in the child scope. Additionally, any variables declared within the new function, and any parameters, will be properties on the child scope. If a child scope defines variables or arguments that have the same name as a property of the parent scope, they will hide the parent scope
s instance.

Examining what is going on above, when sumFunc is called, the global scope contains x. The child scope has inherited the property ‘x’ and added a new property ‘y’ which was in the parameters. When the function ends, there will be no more references to the child scope and it will be disposed of by the garbage collection. The value ‘y’ will not be available to any code. Consider if we change the code slightly:

If you run this code, you will get 4 and 5 displayed, respectively. What is happening is that each invocation of sumFunc results in a new instance of the nested function being created in the current scope, with their unique value of the parameter ‘y’. Exiting the function has not led to the scope being destroyed because the nested function in it’s construction attains a reference to the current scope.

Where closures are interesting is that although JavaScript does not have the concept of private variables, the use of closures can synthesize private members successfully. Consider the following script. I want to create a function that returns the next number whenever it is called.

I create a function that defines a local variable iNext and return from the function a nested function that refers back to iNext. Any function I create in this child scope will always be able to reference the value of iNext. Now when uniqueID is called, the function can reference the variable iNext because it was in scope when the function was created (it doesn’t matter if it is in scope when the function is called).

The really interesting point is that iNext is not programmatically accessible in code. This technique can be extended to synthesize private functions. In the following script the function getSquare is not accessible through code once the self-executing function has run.

The closure of a function is evaluated when the function is assigned to a variable. Consider the following code. When the prototype method area is assigned to the newly created object, ‘this’ is in scope and is the object being constructed. When the function is copied into a global variable, the value of ‘this’ is evaluated again and this time it is the global window object, which does not have a value for width or height.

If we were to add two global variables width and height to the global window object, then copyOfArea would be the product of those two numbers.

It can be seen now why it is necessary to prefix all calls to properties and function for an object with the ‘this’ keyword. At the time of construction, ‘this’ is the object being constructed and all the properties relate to that instance only. That is how properties and function make up a javscript object – through the shared call context when the object is constructed.

Be aware it is important to remember that when coding event handlers that the value ‘this’ is not taken for granted. Consider the following script.

Conclusion

This post has covered the basics of closures in JavaScript. It was shown that functions are a combination of both the their code and the context or scope in which they are called. Interesting closures can be created by returning nested functions from functions containing local variables or methods, and in doing do private members can be synthesized. It is important to keep in mind how scopes can result in the value of “this” being overwritten in event handlers, and a safe approach under these circumstances is refer to a local reference of the “this” object prior to declaring the event handler.

I’m currently working a project with a major focus on insert – throughput and I’d thought I mention a few things I’ve done to improve that throughout that are departures from your typical CRUD .Net application.

Don’t use identities.

They require an additional read immediately after inserting

They defeat insert batching

Use Guid.Comb instead

Creates Guids with just enough order to enable SqlServer to index effectively

Generated by NHibernate without a round trip to the server.

Enables deferment on inserts

Enables insert batching

Lock only aggregate roots and not every entity

Control entity access through repositories for each aggregate root entity.

Using a timestamp results in an additional read after each insert or update

Defeats batching

Use a table per hierarchy instead of a table per subclass (which is the default)

A joined-subclass table strategy requires two inserts, one to the primary table and then the a second to the joined table.

Can’t be batched

Look hard at inheritance hierarchies. Batching only works for entities of the same type, so subclass entities cannot be batched with their base types. I whittled down a few classes and opted for null-properties (exposed as components) rather than subclass – you shouldn’t be building a hierarchy based on data anyway, but behaviour.

Use second level caching for reference objects. I had a few entities were really almost static in nature but need to be referenced by each inserted record. I used the HashtableCache (not really a enterprise cache) to hold these entities. I am not concerned about the cache growing out of control and growing stale, and the application is not clustered so my choice I think stands up. By caching these entities I save a lot of reads from the database.

In general what I have attempted to do is to minimise the calls the database. NHibernate batching is brilliant at this, enabling any number of commands to be issued in a single ADO batch, but it works only under certain conditions.

There were a few other ideas put to me by the local DBA which I haven;t implemented but would consider:

Drop foreign key constraints as the constraints are handled at the application layer

Don’t have a primary key on the inserting tables, rather simply have indexed columns. This would enable SqlServer to heap insert rather than B-tree inserts, which if the primary key is sequential might become problematic as the B-tree would need to rebalance.

It is useful when designing interfaces to be able to define the design-contracts for those interfaces, however because interfaces cannot contain code, CodeContracts cannot be written for them directly. Instead, contracts are defined through the of “buddy” contract abstract classes that are not really classes at all, but just place holders for the contracts in the interfaces.

You can see that the buddy class implements the interface it is the buddy for. Because this buddy class is never intended to be referenced, the actual implementation is not important other than the contracts it defines.

To build the reference assembly, make sure you set the Contract Reference Assembly option to “Build” in the project settings, on the Code Contracts tab.

Using the Reference Assembly

There was surprisingly little information on how to actually use a reference assembly to enforce constraints on interfaces, so I created a test harness as follows:

If the contracts worked and enforced at the interface level, then I should get a null argument exception thrown, else if they don’t work I would get the “NotImplementedException”.

I copied the built interfaces assembly to a separate, new folder location on my machine, leaving the CodeContracts assembly alone for now. I then added a reference to the interface assembly from my client code. When I ran the test, I did not get the contract exception. I then checked the code contracts settings for the project to make sure I was enabling full runtime checking. I then noticed that the Assembly Mode was set to “Custom Parameter Validation” so I changed it to “Standard Contract Requires”, ran the test and still got no contract exception.

I then copied the CodeContracts reference assembly from the first project to the location of the interface assembly and re-ran the test. Still no code contract exception. This was really beginning to bug me.

A burst of inspiration hit me and I re-built the client application (instead of merely re-running it) and well hello, I got the contract exception I was longing for.

I also experimented with locating the contracts reference assembly in the folder called CodeContracts in the same place as the interface assembly, and it works as well.

Conclusion

This post has covered how to use contracts reference assemblies in client applications. It is necessary to either co-locate the reference assembly where the real assembly is placed, or in a folder “CodeContracts” in that location. It is also necessary to turn on CodeContract runtime checking and use “Standard Contract Requires”, and a rebuild is required to pick up CodeContract assemblies.