From Classic ASP to React

Where it all began

I’ve been a software developer for over 16 years. It’s not that long but in terms of software development it’s pretty long time. Perhaps it’s like dog years – 1 development year equals 7 normal person years so actually I’ve been a developer for 112 software dev years. That seems more like it.

Over that time I’ve seen 4 major shifts in web development. Shifts up to new versions happen all the time – this is more where everything you know needs to be put in the bin and you start up again. Seems harsh but that’s the business and if you don’t like it then it’s perhaps time to move on. I’m shifting again to Node.js and React but as I do it’s kind of interesting to look back at the other shifts and how I felt about them at the time and how good they were in retrospect.

Classic ASP

It’s where it all began. Asp files with VBScript and <% %> to poke holes in the html to fit the programming stuff in

It’s all about the response.write. I loved it.

Features

  1. Interpreted language – no compilation
  2. Written in scripting language like VBScript or JScript
  3. One file called *.asp. Everything is in there.
  4. One file per page
  5. Lots of use of Response and Request objects. Felt like you were working with the architecture of the web rather than against it
  6. Stateless

How excited was I to use it?

Ecstatically excited. I loved coding in it. Dynamic web pages that could squirt out content for each individual user. Amazing. It was all interpreted – no compilation here – no need for it. I did this for a Masters project and we all loved it. My supervisor was talking about PhDs in it.

Downsides

It wasn’t perfect. The downsides were

  1. Terrible IDE. It was MS InterDev and it was unusable. We all used to code in EditPad Pro which at least had colours.
  2. No structure. You could put COM+ components in to force some structure into it but you would only do this if you really hated your coworkers.
  3. No debugging unless you count writing acres of Response.Writes all over your code
  4. No state management at all. You want to persist the state of a textbox then do it yourself …

which sets the stage for

ASP.Net Web Forms

A proper compiled language with a new framework and new languages to boot .To get a flavour here is the ubiquitous page load event

Felt radical at the time.

Features

  1. A compiled language – Wow!
  2. Code behind – split files with markup and code in separate files combined with partial statements
  3. Highly abstracted – managed through page life cycle events
  4. Stateful – Automatic state management through View State

How excited was I to use it?

Passed myself with excitement. I got to build a new server first to host it and I had a big silver machine on my desk making a sound like an aircraft for months. And that was just the start – new language, new IDE that worked, proper code and architecture. Who wouldn’t like all this.

Downsides

The world moved past webforms and while they were good initially, the advent of more client side techniques such as AJAX showed it’s limitations

  1. Worked very badly with JavaScript. WebForms mangled HTML element ids and made it difficult to work with
  2. It was really like windows programming for the web. While hiding the complexity of the web might seem good I’m convinced that webform programming led to a cohort of web developers who really didn’t understand the nature of the web.
  3. Inefficient – lots of postbacks and ViewState (stashing the state of the form to persist it) was massive and came over the wire every time.
  4. Very difficult to unit test. Too many tightly bound dependencies
  5. In the end I hated some of the components. Some were good like ListView and some were made for abuse and torture such as the UpdatePanel. Nest these babies and watch the bad times roll.

Things looked a lot brighter over at the Rails community so we got …..

ASP.Net MVC

Model, View Controllers in the Net world. It was a proper architectural pattern that was fully unit testable. It wasn’t pretending to be windows programming – it was the web and it was proud of it. Clearly still very much used today.

How excited was I to use it?

It wasn’t so much as excited – I was relieved. After fighting against webforms, here was something that worked with you. It was almost back to classic ASP in some ways so I felt like I was coming home.

Features

  1. Skinny controllers, dumb Views and fat models
  2. Clever routing so it wasn’t one file per page any more. That more than anything amazed me
  3. Worked well with dependency injection so was testable
  4. Worked well with JavaScript. Generally felt like the web
  5. Stateless again

Downsides

Honestly I just like MVC and always have done. If pushed I might say

  1. It still posts back so not as responsive as it could be
  2. It’s a different stack to front end so you would need to know C# and JavaScript
  3. It’s easy to write badly – massive Views full of logic aren’t good

But while we weren’t looking Node.js was discovered and we get….

React

Or I could have said Angular or Ember or fill in the blank with your favourite framework. For me, it’s the most radical shift yet because it’s not the Microsoft stack – we’re not in Kansas any more. It’s all in JavaScript, even the server. And while it’s not restricted to the client it’s focus is around ‘reactive’ single page applications (well my focus is anyway).

Features

  1. Highly componentised
  2. JavaScript with HTML like syntax embedded in
  3. Single page application (often)
  4. View only .
  5. Blazing fast if on single page app – uses Virtual DOM to only update what it needs to on the page
  6. Back to stateful (if on single page app)

How excited am I to use it?

I feel pretty fortunate to have to opportunity to use this in a commercial setting. I’ve always liked JavaScript and it’s fascinating to see it build out a large scale application. I like Angular for the same reason. So I’m excited once again.

Downsides

It’s not all gravy though. Downsides include

  1. It is a steep learning curve and fast moving so the curve keeps shifting
  2. It’s JavaScript which is great but it’s easy to write terrible JavaScript so terrible React
  3. You’ll need a decent architecture to go with it like Redux – not a disadvantage but you need to be aware of it
  4. It’s just the view so the rest is up to you to (re)invent.

Looking Back and Looking forward

I feel all misty eyed looking back and this is just one aspect of the development I’ve been involved in. There’s ORMs, mobile development, testability, ASP Core, the rise of Dev Ops and on and on and on. Headspinning but great.

What’s next – it’s just so hard to say. I reckon .Net Core will take off, JavaScript will be replaced or transform to something unrecognisable, everyone will decide they hate ORMs and rediscover stored procedures, machine learning will be big, driverless cars will start to fly and we will all go to live on Mars with Elon Musk. Or maybe someone will invent a web framework which combines the best of classic, web forms, mvc and react; perhaps like this ……

  • The simplicity of classic ASP
  • The rapid development capabilities of web forms
  • The testability of MVC
  • The blazing speed of React

Can someone invent that one please.

Useful Links

https://www.w3schools.com/ASp/asp_examples.asp
Classic ASP examples

https://msdn.microsoft.com/en-us/library/ms178472.aspx
WebForms page management life cycle

https://www.asp.net/mvc
Microsoft site for MVC

https://reactjs.org/
Main page for react from FaceBook this time

Better Numeric Range Input with ASP.NET MVC, HTML5 and JQuery

The Sin

I recently wrote this horrible code to generate a drop down box to select any number from 1 to 12.

Ouch! It was only a test harness but after an hour I still got sick of looking at it. It’s a sin that needs to be atoned for.

The Penance

For my penance I’ve said 5 Hail Marys and identified three better ways to generate numeric range dropdowns.

Using Enumerable.Range

If I want to stick with MVC and C# then there is a static method on Enumerable that will generate sequences of numbers i.e.

Will output 1 through to 12 as a list of ints. Leveraging this, my grotesque piece of Razor becomes

Which renders out as a normal dropdown as before

Enumerable.Range

Much better.

Using HTML5

Of course we don’t even need to get into C#. If we’ve got the luxury of a modern browser we can just use HTML5 to give us a slider control.

Which renders as

HTML5

Better again.

Using JQuery

If you don’t have the luxury of a modern browser then you can fall back to JQuery UI which has a larger range of supported browsers. The code isn’t that much more but of course you need to reference JQuery and JQuery UI libraries. It’s another slider type control and the implementation is

Which looks like

JQuery UI

So much nicer.

The Atonement

To atone for my sin I swapped out the horrible code for the Enumerable.Range implementation. I think that’s my preference really. I don’t really want to include a whole bunch of scripts and css to get a decent control (JQuery) and I don’t want to limit myself to the latest and greatest browsers (HTML5). Beside I think Enumerable.Range is little known but pretty smart and let’s face it – who doesn’t want to be little known but pretty smart.

Useful links

https://www.dotnetperls.com/enumerable-range
Nice article on Enumerable.Range

http://www.htmlgoodies.com/html5/tutorials/whats-new-in-html5-forms-handling-numeric-inputs-using-the-number-and-range-input-types.html
More on the HTML slider control

https://jqueryui.com/slider/
Official documentation for the JQueryUI slider control

https://github.com/timbrownls20/Demo/blob/master/ASP.NET%20Core/Demo/Demo/Views/Demo/NumericDropdown.cshtml
As always there are code sample of all implementations on my git hub site.

 

Handlerbars.js and Working with Complex Objects in MVC

In a previous post I used an EditorFor template to display child objects correctly on a view. Now we are going to use some simple JavaScript templating to add child objects. We have a page display book details and want to add and save additional authors.

Demo app

The demo app is a simple bookshelf application. It has a view that uses EditorFor templates to display a book which we want to save. The book can have multiple authors. It is a complex object.

The book is rendered onto the Book.cshtml view and the user sees a book then can be edited and saved as required.

authors-correct-display

The authors are rendered in this format

When this form is posted back, the default model binder in MVC uses the name attribute to correctly bind the authors as a child object of the book object. So we get a correctly populated book object passed through to the controller action.

The book parameter is populated will the correct authors. Nice. In general, to work with child objects the correct format for the name attribute in the HTML form element is ..

We’ll need to bear that in mind when we are creating a control to add new authors.

The Problem

The authors display correctly and work well but what if we want to add additional authors to the book before saving? Perhaps the book is missing authors. Perhaps I’m a rampant egotist and want to add myself as an author to every book in my virtual bookshelf. Let’s use Handlerbars.js and some JQuery goodness to do this.

The Solution

Handlebars.js

Handlebars.js is one of many JavaScript templating engines that bind fragments of HTML and produce data driven templates. Handlebars takes a template such as

And binds it against some JSON

To produce HTML

That’s going to be good for us. We’ve got some pretty chunky fragments of HTML and we want to work with it in the cleanest way we can.

Integrating Handlerbars.js into MVC

Install the package using nuget

In it goes to the application. Now create a script bundle in BundleConfig.cs

and reference that bundle in the view

Creating the HandleBar template

Let’s dive straight in and create the template. We want a HTML fragment that will generate us a new author. HandlerBar templates need to be in script tags with the type

our full template is

This gives us a hidden field for the AuthorID and a text field for the author name. The curly brackets tell us where the holes in the template are so

Are the two pieces of data that the template needs. Handlebars will replace these with the data we supply it.

Constructing the Author add control

Now we need a HTML control to add the author. We want something like this

authors-with-add-button

So a textbox and a button with a squirt of CSS

Let’s assume that JQuery is already reference and available. Next job is to wire up the click event to the button

Which is standard stuff.

Obtaining the data for the template

Next we need to construct the JSON data that Handlebars will use to generate the HTML. We need two pieces of information

  1. The authors name as inputted by the user
  2. The next index of the author elements

Grabbing the author name is straightforward

However to get the next index we need find the current highest index. First we need to navigate the DOM to find the last author. The authors are all wrapped in the ‘shelf-authors’ class to facilitate this

then we want the name attribute

Then we want the last index. If there are 3 authors then lastAuthorFormName will contain

So some regex the current index i.e. the number in square brackets

The entire regex matches “[2]” and the first and only group (\d*) matches the digit itself. The output for this is an array. The first element of the array is the full match. All subsequent elements are the matches for the containing groups (defined in regex by parenthesis). So

would equal “[2]” and

would equal “2”.  So to get the next index we need

Now we have all the information we need to construct the data for the handlebar template

Gluing the template together

Gluing the data into the template is pretty much boilerplate code

Grab the template with a CSS selector then compile and combine. The HTML is now correct and can be inserted into the DOM

The Complete Solution

So combining all the steps together we get

The HTML element is now correct and when this is posted back the new author will be present in the action method i.e.

The book parameter will have a fourth author which will be saved.

author-successfully-added

So I can now add myself as an author to every book in my library which goes some way into feeding my monstrous and uncontrolled ego – which is what it’s all about really.

Useful Links

Project page for handlebars
http://handlebarsjs.com/

Nuget page for handlebars
https://www.nuget.org/packages/Handlebars.js/

Demo application source
https://github.com/timbrownls20/BookShelf/

 

ASP.Net MVC and Binding Complex Objects Magic

I’ve a habit of declaring things magical when I don’t fully understand how they work and haven’t the time to look into them any further. One of the things I’ve often declared magical is model binding with MVC. It just works. Magical.

Recently though I found model binding with child objects a bit on the difficult side of things. The magic was failing to sparkle correctly and needed a little bit of extra developer sprinkles to work. Perhaps it even needs developer understanding.

Demo Application

I’m going to demonstrate the problem and solution using a demo library application. The application queries Google Books API and allows users to edit and add those books to their own virtual bookshelf. The book shelf app can be found here

https://github.com/timbrownls20/BookShelf/

 Workflow

The relevant part of the application is adding of books to the library. The work flow is …

  1. User searches for a book
  2. Application queries GoogleBooks and displays a list of matches
  3. User selects a book
  4. Application displays the selected book.
  5. The user amends the book record as required
  6. The application saves the book

So once the user has typed in a search term they are presented with a list of books which they can select.

book list
Save.cshtml

Once selected a view showing the detail of the book is present to the user. The user is invited to save the book into his or her book shelf.

authors-incorrect-display
Fig 2: Book.cshtml

The problem is that the authors are not saved correctly. It’s pretty obvious that the authors aren’t displayed correctly. The HTML output looks fairly nonsensical.

We are going to have to dig into the application a bit further to fully understand this.

The Model

The model of the application is

So a book can have multiple authors. It is a complex object. It is the complex object and how that is rendered on the Book.cshtml view that causes us the problem. When it is posted back the book object lacks authors. The binding of the complex model has failed.

Book Create Action

When the user selects a book from this list this action is called. It displays the book ready for a save. We pass in an id (from the list selection) then the service goes away and grabs the full details of the book.

The book is then displayed on the view Save.cshtml. The user presses submit which posts the book back to the server.

Book Save Action

This action is called when the user saves a book to his or her bookshelf. The posted back book is saved.

This action takes the book object and it is here that we want form data to bind and produce the complex object. We want the model binding to produce the book object as a parameter. We want the magic. The magic fails us.

The Problem

It doesn’t just magically work much to my disappointment. What is displayed is not helpful.

authors-incorrect-display
Fig3. Book.cshtml with incorrect author display

Posting this page doesn’t binding the child object and the authors aren’t there. The HTML is just not there. So how can I easily, and with as much magic as possible, change the view so that the authors are present and the form elements are named correctly? What does the default model binder actually want and how can I provide it?

The Solution

EditorFor Templates

The view needs to know how to display the author object. I could loop through in in the view but a better solution is the EditorFor template.

In View/Shared/EditorTemplates create a file called Author.cshtml. By convention MVC will find this and use it to display the Author property. We are telling it what to write out when the author property is edited i.e. what HTML to write out when the following call is made in the view

The Author.cshtml is pretty simple

The Corrected View

Now this is in place the view looks a lot better and it works.

 

authors-correct-display
Fig 4. Book.cshtml with corrected author functionality

When save is pressed the full object is passed to the Save Action and the object included authors can be persisted

What is interesting is the rendered output. Viewing the page source (stripping out the validation data elements, styling etc..) we see this

So the convention that the default model binding requires is revealed. I wouldn’t have just guessed it but the EditorFor Template does it for us.

Although both the id and name look like reasonable candidates for model binding, it is the name attribute that is used. The format for child objects is

so more complex objects are perfectly possible

and so on until you gone down a complex rabbit hole of 7 nested objects from which you might never return.

Adding New Authors (child objects)

One of the things we might want to do is enable a user to add new authors. Perhaps the retrieved book doesn’t have all the authors and the user is a stickler for detail. Knowing the required format of the child object html is going to help us with that. In its very simplest form it could a bit of jQuery based on this idea

But we would need to bit cleverer, use templating, work out the next index etc… But this gives us the starting point to be able to provide that functionality. An exercise for another day perhaps.

Note
I’ve now implemented a solution using Handlebars.js to add authors into the complex object. See this post for details.

DisplayFor Templates

As an aside we could/should also do a template for displaying a read version of the model i.e. when the following call is made in a view.

It’s not needed to get this to work but it seems like a generally good and wholesome thing to provide this as well. The display template can be very simple..

 Useful Links

More detail about EditorFor and DisplayFor templates
http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm

Some more insight into how complex data binding works
http://blog.codeinside.eu/2012/09/17/modelbinding-with-complex-objects-in-asp-net-mvc/

How to manipulate the DOM through JQuery which we would need to dig into a bit to implement adding an author
http://api.jquery.com/category/manipulation/

Google Books API reference in the blog post
https://developers.google.com/books/