Friday, February 24, 2012

Using knockout.mapping Plugin with Asp .Net MVC – Part 1a

In part 1 of this series I explored knockoutjs and completed a simple display view in the UI.

A few people have spoken to me about the implementation and commentated on what they perceived as a leakage into the Separation of Concerns regarding how bindings are managed via the data-bind attributes. While the comments certainly led to some interesting debates, I thought how can I remove some of those Concerns away from the UI.

Some research and I came across Neil Kerkin's blog post Exploring TodoMVC and knockout.js with unobtrusive bindings where he discusses an approach using knockout.js supports custom binding providers that allow us to refactor the code to achieve a bit more separation.

I won't go too much into what I have done because Neil explains it a lot better than I could. Therefore I'll just post the newer code base that will be used for part 2.

The javascript which looked like the following:

Code Snippet

(function (getworkouts, $, undefined) {    //create view model and initialise with default data.
    getworkouts.viewModel = function() {
        this.workouts = ko.mapping.fromJS(
                    [],
                    {
                        key: function (workout) { return ko.utils.unwrapObservable(workout.Id); }
                    });
                };    //use ajax call to populate the view model from the Action and also bootstraps knockout
    getworkouts.getDataFromSource = function () {
        $.ajax({
            type: 'POST',
            url: '/Home/GetWorkouts',
            dataType: 'json',
            success: function (data) {
                var model = new getworkouts.viewModel();
                model.workouts = ko.mapping.fromJS(data);
                ko.applyBindings(model);
            }
        });
    };
} (window.getworkouts = window.getworkouts || {}, jQuery));$(document).ready(function () {
    //bootstrap call
    getworkouts.getDataFromSource();
});


becomes

Code Snippet



/* File Created: February 5, 2;01;2 ;*/

(function (getworkouts, $, undefined) {

    window.setUpBindings.SetCustomBindings();

    //create view model and initialise with default data.

    getworkouts.viewModel = function () {

        this.workouts = ko.mapping.fromJS(

                    [],

                    {

                        key: function (workout) { return ko.utils.unwrapObservable(workout.Id); }

                    });

    };

    //use ajax call to populate the view model from the Action and also bootstraps knockout

    getworkouts.getDataFromSource = function () {

        $.ajax({

            type: 'POST',

            url: '/Home/GetWorkouts',

            dataType: 'json',

            success: function (data) {

                var model = new getworkouts.viewModel();

                model.workouts = ko.mapping.fromJS(data);

                getworkouts.bindings = {

                    workouts: { foreach: model.workouts },

                    workoutsDateTime: function () { return { text: this.DateTime }; },

                    workoutsWorkoutName: function () { return { text: this.WorkoutName }; }

                };

                //set ko's current bindingProvider equal to our new binding provider

                ko.bindingProvider.instance = new ko.customBindingProvider(getworkouts.bindings);

                ko.applyBindings(model);

            }

        });

    };

} (window.getworkouts = window.getworkouts || {}, jQuery));

$(document).ready(function () {

    //bootstrap

    getworkouts.getDataFromSource();

});

    



With an additional javascript snippet of

Code Snippet



/* File Created: February 16, 2012 */

(function (setupBindings, $, undefined) {

    setupBindings.SetCustomBindings = function() {

        ko.customBindingProvider = function(bindingObject) {

            this.bindingObject = bindingObject;

            //determine if an element has any bindings

            this.nodeHasBindings = function(node) {

                return node.getAttribute ? node.getAttribute("data-class") : false;

            };

            //return the bindings given a node and the bindingContext

            this.getBindings = function(node, bindingContext) {

                var result = { };

                var classes = node.getAttribute("data-class");

                if (classes) {

                    classes = classes.split(' ');

                    //evaluate each class, build a single object to return

                    for (var i = 0, j = classes.length; i < j; i++) {

                        var bindingAccessor = this.bindingObject[classes[i]];

                        if (bindingAccessor) {

                            var binding = typeof bindingAccessor == "function" ? bindingAccessor.call(bindingContext.$data) : bindingAccessor;

                            ko.utils.extend(result, binding);

                        }

                    }

                }

                return result;

            };

        };

    };

} (window.setUpBindings = window.setUpBindings || {}, jQuery));



The view then becomes

Code Snippet



<tableclass="gridtable">

    <thead>

        <tr>

            <th>

                Date Of Workout

            </th>

            <th>

                Name Of Workout

            </th>

        </tr>

    </thead>

    <tbody data-class="workouts">

        <tr>

            <td>

                    <span data-class="workoutsDateTime"></span>

            </td>

            <td>

                    <span data-class="workoutsWorkoutName"></span>

            </td>

        </tr>

    </tbody>

</table>



Once again the code is available at Github.

I've rushed over the implementation mainly because I don't want to any credit away from Neil Kerkin's solution to the Separation of Concerns problem.

See you at part 2.

Saturday, February 18, 2012

First MVC and now Web Api Microsoft is on a roll

The newly release Web Api is the next version of the excellent WCF Web API.

ASP.NET Web API is a framework for building and consuming HTTP services that can reach a broad range of clients including browsers and mobile devices. It’s also a great platform for building RESTful services. ASP.NET Web API takes the best features from WCF Web API and merges them with the best features from MVC.

The integrated stack supports the following features:

  • Modern HTTP programming model

  • Full support for ASP.NET Routing

  • Content negotiation and custom formatters

  • Model binding and validation

  • Filters

  • Query composition

  • Easy to unit test

  • Improved Inversion of Control (IoC) via DependencyResolver

  • Code-based configuration

  • Self-host


More information can be found at Web Api. the official Microsoft Web Api web site.

Over the past 11 years I've used asmx web services, ashx handlers and WCF services to build consumable web services. Recently I've ditched WCF as being too cumbersome and configuration heavy to use MVC as a poor man's Web service provider. Using Action Filters to create XML and JSON outputs dependent on the client request it made developing web service endpoints so much easier.

Now with the new Web Api solution from Microsoft all the MVC goodness (routes etc) and the good bits from WCF Web Api seems to have given a solid Web Services base to build robust .Net Apis with ease.

Initial set up is relatively easy either via NuGet or the ASP MVC 4 beta release installer

I'll endeavour to get a sample up very soon, hopefully as part of my Knockout js series.

In the meantime go to the Web Api home page or have a look at Jon Galloway's blog, ASP.NET MVC 4 Beta Released!, which contains an informative section on the ASP.NET Web API.

Tuesday, February 7, 2012

Using knockout.mapping Plugin with Asp .Net MVC - Part 1

Knockout is a JavaScript library that makes it easier to create rich, desktop-like user interfaces with JavaScript and HTML, using observers to make your UI automatically stay in sync with an underlying data model.

In this post I am going to show how ASP .Net MVC and Knockout can compliment each other to allow for a rich client side user experience.

Starting with an Empty MVC 3 application in Visual Studio let's start with some dependencies:
PM> install-package knockoutjs

PM> install-package Knockout.Mapping
PM> update-package //running this last command will update bundled packages that MVC 3 comes with (jQuery etc).

Installing the above packages will give you the javascript files required for Knockout and the Knockout Mapping plugin.

I highly recommend reading the documentation on the Knockout js site for a solid background of what Knockout can do to help solve client side functionality problems.

Now that we have the pre-requisites let's build a model to interact with:


Code Snippet

public class Workout
    {
        public long Id { get; set; }
        public string DateTime { get; set; }
        public string WorkoutName { get; set; }
    }



Now that we have a model we need to present it to the user.

Let's start with a view that shows all workouts in a tabular format. The html output I want is as such:

Html Layout for Knockout

To achieve that I need to replicate the html code as follows:


Code Snippet



  1. <table class="gridtable">

  2.     <thead>

  3.         <tr>

  4.             <th>

  5.                 Date Of Workout

  6.             </th>

  7.             <th>

  8.                 Name Of Workout

  9.             </th>

  10.         </tr>

  11.     </thead>

  12.     <tbody>

  13.         <tr>

  14.             <td>

  15.                 24/12/2011

  16.             </td>

  17.             <td>

  18.                 Full Body Workout 1a

  19.             </td>

  20.         </tr>

  21.         <tr>

  22.             <td>

  23.                 25/12/2011

  24.             </td>

  25.             <td>

  26.                 Full Body Workout 2a

  27.             </td>

  28.         </tr>

  29.     </tbody>

  30. </table>





Let's set up a Action on the Home controller to return a JsonResult.




Code Snippet



  1. public JsonResult GetWorkouts()

  2.         {

  3.             var model = new List<Workout>

  4.                             {

  5.                                 new Workout

  6.                                     {DateTime = DateTime.Now.AddDays(-7).ToShortDateString(), Id = 1, WorkoutName = "Full Body Workout 1a"},

  7.                                 new Workout

  8.                                     {DateTime = DateTime.Now.AddDays(-6).ToShortDateString(), Id = 2, WorkoutName = "Full Body Workout 2a"}

  9.                             };

  10.  

  11.             return Json(model);

  12.         }





Now for the javascript to initalise knockout and set up the inital data for the view model.



Code Snippet

(function (getworkouts, $, undefined) {

    //create view model and initialise with default data.
    getworkouts.viewModel = function() {
        this.workouts = ko.mapping.fromJS(
                    [],
                    {
                        key: function (workout) { return ko.utils.unwrapObservable(workout.Id); }
                    });
                };

    //use ajax call to populate the view model from the Action and also bootstraps knockout
    getworkouts.getDataFromSource = function () {
        $.ajax({
            type: 'POST',
            url: '/Home/GetWorkouts',
            dataType: 'json',
            success: function (data) {
                var model = new getworkouts.viewModel();
                model.workouts = ko.mapping.fromJS(data);
                ko.applyBindings(model);
            }
        });
    };
} (window.getworkouts = window.getworkouts || {}, jQuery));

$(document).ready(function () {
    //bootstrap call
    getworkouts.getDataFromSource();
});



As you can see I use a Self-Executing Anonymous Function to help protect the global namespace.

Let's dissect the javascript.

First we create a public property on the View Model called workouts, this will store the array of workouts to be displayed to the client. Next we create a bootstrapping function, see the function named getDataFromSource. This makes a jQuery ajax call to /Home/GetWorkouts, an action on the Home controller that returns a JsonResult which represents the data to be presented. The line model.workouts = ko.mapping.fromJS(data); is particularly interesting. The mapping plugin for Knockout gives you a straightforward way to map a plain JavaScript object into a view model with the appropriate observables. This provides an alternative to manually writing your own JavaScript code to construct the view model. That is instead of writing a lot of boilerplate code you can write one line and get on with writing the rest of your application. Finally calling ko.applyBindings(model); initialises knockout.

All that is needed now is the UI set up.




Code Snippet

<table class="gridtable">
    <thead>
        <tr>
            <th>
                Date Of Workout
            </th>
            <th>
                Name Of Workout
            </th>
        </tr>
    </thead>
    <tbody data-bind="foreach: workouts">
        <tr>
            <td><span data-bind="text: DateTime"></span></td>
            <td><span data-bind="text: WorkoutName"></span></td>
        </tr>
    </tbody>
</table>



This will iterate over the workouts property and produce the relevant tr elements and text to produce Html as we were expecting.

The source code is available here at github

My next post in this series will add Edit/Delete functionality to the application until then I hope that this post has presented the reader with an overview of a possible approach for a real life knockout and MVC 3 based application.

Sunday, January 8, 2012

Using TortoiseGit UI from posh-git

Over the past six months I've become a massive fan of Git as Version Control System (VCS). In my career I've used the following flavours of Version Control Systems:

  • File system - NOT recommended

  • Visual Source Safe

  • Subversion - under the guise of TortoiseSvn

  • Mercurial - under the guise of TortoiseHg and then using the command line

  • Git - using the command line but also sometimes the TortoiseGit UI.


The latest VCS, Git, (or more specifically Distributed VCS (DVCS)) has been my favourite to use. I truly believe it's speed and features really help the RAD (Rapid Application Development) process.

I currently use Console++ as my powershell command line:



To set this up I used this article by Danny Douglass, A Better Hg Command Line Interface: Console2 + PowerShell + Posh-Hg. I use this Gist to allow the use of both posh-git and posh-hg on the same machine.

One thing I do miss sometimes is TortoiseSvn's GUI especially for checking for modified files. The way you can double click the line to get a diff of the file is excellent.

For a while I've been manually launching TortoiseGit to get the interface:



Until today, today I found a file in posh-git named TortoiseGit.ps1. This gives command line access to TortoiseGit using the following alias tgit.

An example,



tgit commit will launch the TortoiseGit interface. How cool is that.

The commands that can be used are about,log, commit, add, revert, cleanup, resolve, switch, export, merge, settings, remove, rename, diff, conflicteditor, help, ignore, blame, cat, createpatch, pull, push, rebase, stashsave, stashapply, subadd, subupdate, subsync, reflog, refbrowse and sync

Happy Versioning.

Monday, November 7, 2011

PRG Pattern - How to Keep MVC ModelState

According to the definition of the HTTP POST and GET verbs:

  1. HTTP GET is used for non-changing (idempotent) data to your model.

  2. HTTP POST is used for changing data to your model.


Given this clear delineation, when receiving form data in your post back action method, return RedirectToAction(), which will result in a HTTP 302 (temporary redirect) and will generate a GET on the. This results in Post-Redirect-Get pattern.

One of the issue with this pattern, when using Asp .Net MVC, is that when validation fails or any exception occurs you have to copy the ModelState into TempData. Kazi Mansur has a great solution posted here under the sub section "13. Use PRG Pattern for Data Modification".

The examples he shows is:

[sourcecode language="csharp"]
public abstract class ModelStateTempDataTransfer : ActionFilterAttribute
{
protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName;
}

[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard"), StoryListFilter, ImportModelStateFromTempData]
public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page)
{
//Other Codes
return View();
}

[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData]
public ActionResult Submit(string userName, string url)
{
if (ValidateSubmit(url))
{
try
{
_storyService.Submit(userName, url);
}
catch (Exception e)
{
ModelState.AddModelError(ModelStateException, e);
}
}

return Redirect(Url.Dashboard());
}
[/sourcecode]

and for the Action Filter itself

[sourcecode language="csharp"]
public class ExportModelStateToTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//Only export when ModelState is not valid
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
//Export if we are redirecting
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}

base.OnActionExecuted(filterContext);
}
}

public class ImportModelStateFromTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;

if (modelState != null)
{
//Only Import if we are viewing
if (filterContext.Result is ViewResult)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
else
{
//Otherwise remove it.
filterContext.Controller.TempData.Remove(Key);
}
}

base.OnActionExecuted(filterContext);
}
}
[/sourcecode]


I like the way this has been handled but because I like to learn from other people's ideas I also like to use the workflow for HTTP POSTs as described by Jimmy Bogard in his post, Cleaning up POSTs in ASP.NET MVC.

In short each action that requires a POST using the following ActionResult:

[sourcecode language="csharp"]
public class FormActionResult<T> : ActionResult
{
public ViewResult Failure { get; private set; }
public ActionResult Success { get; private set; }
public T Form { get; private set; }

public FormActionResult(T form, ActionResult success, ViewResult failure)
{
Form = form;
Success = success;
Failure = failure;
}

public override void ExecuteResult(ControllerContext context)
{
if (!context.Controller.ViewData.ModelState.IsValid)
{
Failure.ExecuteResult(context);

return;
}

var handler = ObjectFactory.GetInstance<IFormHandler<T>>();

handler.Handle(Form);

Success.ExecuteResult(context);
}
}[/sourcecode]

Which not only cleans up the POST workflow and makes testing so much easier but it also helps separate application concerns. In the original Action Filter there is a guard clause to ensure that the Filter Context result is either a RedirectResult or a RedirectToRouteResult

[sourcecode language="csharp"]
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
[/sourcecode]

So how do we add the clause so that the result can be of the Generic type of FormActionResult? By using reflection.
[sourcecode language="csharp"]
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult) || (filterContext.Result.IsTypeOfGeneric(typeof(FormActionResult<>))))
[/sourcecode]

where the signature IsTypeOfGeneric is an extension method which looks like the following:
[sourcecode language="csharp"]
public static bool IsTypeOfGeneric<T>(this T source, Type genericTypeToCompare)
{
if (!genericTypeToCompare.IsGenericType)
throw new ApplicationException(@"Compare type needs to be generic");

if (!source.GetType().IsGenericType)
throw new ApplicationException(@"Base type needs to be generic");

return source.GetType().GetGenericTypeDefinition()==genericTypeToCompare;
}
[/sourcecode]

The msdn definition of the method GetGenericTypeDefinition is here

Now we can use FormActionResult within our code and the ModelState will be saved from the POST to the GET.

Tuesday, September 6, 2011

ASP Webforms Lifecycle

Last week the following question came up at work:
what's the event order for a masterpage with usercontrols?

In response I pointed to a blown up printed version of the ASP .NET page Lifecycle for .Net 2.0 runtime Cheat sheet ASP .NET page Lifecycle for .Net 2.0 runtime.

I've found it to be an exceptional resource tool.

The blog post relating to the cheat sheet can be found at Kris' blog. Kudos for Kris for sharing it.

All credits go to the original designer of the diagram: Léon Andrianarivony.

Friday, July 8, 2011

MVC3 Security: A Fluent Way

In Asp MVC you can control user authorization by using security attributes to decorate the controller actions for authorization, for example, in the following AccountController class, the Authorize attribute decorates the ChangePassword action method so it will only allow logged in users to change their passwords. One way to test this is,


Code Snippet

[Test]
        public void Verify_ChangePassword_Method_Is_Decorated_With_Authorize_Attribute()
        {
            var controller = new AccountController();

            var type = controller.GetType();
            var methodInfo = type.GetMethod("ChangePassword", new Type[] { typeof(ChangePasswordModel) });

            var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);
            Assert.IsTrue(attributes.Any(), "No AuthorizeAttribute found on ChangePassword(ChangePasswordModel model) method");
        }



While the above code certainly tests that the Change Password method has the Authorize Attribute the usage of Reflection is quite heavy. For me it makes the test a bit too verbose. Enter the Fluent Security framework. To quote the website “Fluent Security provides a fluent interface for configuring security in ASP.NET MVC. No attributes or nasty xml, just pure love.” Also available via NuGet:

[sourcecode language="csharp"]
PM> Install-Package FluentSecurity
[/sourcecode]

Fluent Security enables the implementation of configuration based security. Let’s start by removing the Authorize attribute from the Account Controller:


Code Snippet

[HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }



Now to configure Fluent Security to secure the ChangePassword action, you can place the code the the Application start event of the Global.asax file. I prefer keep as much code out of that as possible and use a Application Bootstrapper.


Code Snippet

public class SecurityBootstrapper : IBootstrapThisApp
        {
            public void Execute()
            {
                SecurityConfigurator.Configure(configuration =>
                {
                    // Let Fluent Security know how to get the authentication status of the current user
                    configuration.GetAuthenticationStatusFrom(() => HttpContext.Current.User.Identity.IsAuthenticated);

                    // This is where you set up the policies you want Fluent Security to enforce
                    configuration.For<HomeController>().Ignore();

                    //configuration.For<AccountController>().DenyAuthenticatedAccess();
                    configuration.For<AccountController>(x => x.LogOff()).DenyAnonymousAccess();
                });

                GlobalFilters.Filters.Add(new HandleSecurityAttribute(), 0);
            }
        }

        public interface IBootstrapThisApp
        {
            void Execute();
        }



By default Fluent Security will throw an exception if a missing configuration is encountered for a controller action. If you don't want Fluent Security to handle security for all controllers you can tell it to ignore missing configurations. You can do this by adding configuration.IgnoreMissingConfiguration(); to your configuration expression. Testing becomes pretty simple using Fluent Securities Test Helper, available as a NuGet package.



Code Snippet

[Test]
        public void Should_Have_Correct_Security_Configuration()
        {
            new SecurityBootstrapper().Execute();
            var results = SecurityConfiguration.Current.Verify(x =>
            {
                x.Expect<HomeController>().Has<IgnorePolicy>();
                x.Expect<AccountController>().Has<DenyAuthenticatedAccessPolicy>();

                x.Expect<AccountController>(y => y.LogOff()).Has<DenyAnonymousAccessPolicy>().DoesNotHave<DenyAuthenticatedAccessPolicy>();
            });

            Assert.That(results.Valid(), results.ErrorMessages());
        }




I've only just started to implement security using the above methods and so far I am liking the framework. Testing becomes easier and it's a lot easier to get an overview of your Web Applications Security configuration