Model binding dynamic collections. I

 
event

Some months ago had the chance to do some MVC for a client of my company.

I will be writing about some of the (hopefully) interesting and helpful things I did.

The requirements

I inherited an existing MVC web application that managed (mostly CRUD-ly) a number of items and I was in charge of a completely new area (functional area, not MVC area) to edit existing entities as well as create new ones.
Those entities contained a bunch of information, inside which was a list of related entities. So a container, contained its own information as well as a list of things with their own information.

The way people worked was pretty similar to what spreadsheet-trained people do:

  1. open a document
  2. do a bunch of changes
  3. persist those changes by hitting “Save”

And what they wanted to do was pretty similar:

  1. open an entity for update
  2. perform a bunch of operations on it
  3. save all the changes for that entity

Amongst the bunch of operations they could do, there was a subset that are interesting (but not uncommon):

  • sorting the elements of a list
  • deleting a given element of a list
  • adding new elements to a list

Another requirement was that the application was to be very responsive to their actions, which ruled out most of the round-trip-to-the-server scenarios, unless the application was to be completely re-written (not an option by itself). They wanted to drag stuff around to sort, and get instant feedback of deletions.

For the sake of simplicity, we are going to exemplify those scenarios (sorting, deleting and adding) in an isolated manner, although, in the real solution, the three things were done at the same time in no particular order.

An Alternative solution

I want to be clear from the beginning: the solutions I implemented for the problems at had are, by no means, the absolute best solutions.
They are solutions, nonetheless, that allowed me to write as little code as possible by leveraging existing assets.

Going all asynchronous

One alternative solution was go completely asynchronous: whenever an operation was performed client-side, it could have been notified to the server and asynchronously performed and the list of entities persisted to their storage.
There could even be some clever undo operation to go back in time (remember the users are used to save all changes at once).

It is a perfectly fine solution, but I chose not go that route as involves writing a lot of plumbing code to gather information in the client (or the use of a client-side binding framework) and a bunch of data-endpoints able to handle each of the operations. (remember we are supposed to do all operations at once).
Besides, I am not the brightest Javascript developer, nor I have any real-world experience with those client binding/MV* frameworks.

My solution

My solution is built around the realization that server-side model binding is a wonderful thing. It is extensible, but out-of-the-box solves a ton of problems that, before, had to be specifically (and often manually) solved.

Of course, I am aware that not every problem can (or should) be solved in the server, and a bit of client-side makeup will round-up the experience.