Mobilize Blog

Application Modernization

WebMAP app architecture part 1

Posted by John Browne on May, 03, 2016 @ 07:05

Historically we at Mobilize have focused on tools to transform app source code from one desktop platform to another, newer, desktop platform--the best known of these is VBUC which moves VB6 to .NET. 

More recently we developed and released WebMAP to move desktop (C#/Winforms/.NET) apps to a modern web architecture. Because this is such a major paradigm shift (desktop to web) it leaves some desktop developers scratching their heads a little when they look a the migrated code and wonder "where's my class/form/event handler/etc?"

First of all there are a lot of differences between a Windows app and a web app, not the least of which is the physical separation between client and server. I wrote about some of these issues here; if you're unfamiliar with web development this is a good place to start.

In this series I want to explore the architecture that WebMAP creates following a migration. Since we are using a hybrid pattern pieces of it may be familar to you but overall some explanation is called for.

First of all, let's clarify exactly what we mean by the word "WebMAP:"

  • tool for migrating source code from one platform to another
  • set of helper classes in C# that are part of the new, migrated app
  • An architecture of the new, migrated app.

The tool is proprietary; the helper classes are included in the created app and are easily read for understanding; the architecture is the subject of this (and subsequent) blog posts. Note that you probably won't need to spend a lot of time with the helper classes as they handle the "under the hood" stuff to make your app run. At least some familiarity will be helpful when you are debugging your app, however.

One tier or two?

As I mentioned above, the key difference between a desktop app and a web app is that the web app (and by that I mean the kind of modern web app we create) is a multi-tier application that is divided into a front end (ie client running in a browser) and a back end (server running remotely in a datacenter or cloud). Another key difference is that on the desktop you normally have a single user with a dedicated execution thread and on a web app the server needs to handle mutiple requests all sharing an execution thread. Those two differences make for lots of changes in the app architecture.

Remember we are talking about applications on the browser, not web pages. Web pages--even interactive ones--are pretty simple compared to re-creating the functionality and UX of a desktop app in a browser. For our discussion it's helpful to assume any app we are talking about is heavily forms-based with a database back end. In a Windows application a traditional way to handle these kinds of apps was a "code-behind" approach where events on controls triggered handler code. Even with older ASP.NET ("classic") apps using webforms they supported this paradigm. 

Our architecture uses a different paradigm: one that might be a little intimidating initially but that has big benefits over the "code behind" approach.

Front ends and back ends

First consider that the app has to be instantiated as a browser session. This means either we use some plug-in approach like Flash or Silverlight (both of which are losing support in modern browsers due to security concerns) or we have to generate pure standardized code like HTML, CSS, and JavaScript. Those will all run on all modern browsers and you shouldn't need hacks asking the browser what it can support, unless deep backwards compatibility is important to you. This combination of HTML5, CSS, and JS--especially adding on some sort of JS framework--can create very powerful and completely portable user experiences in the browser. For our purposes we will use one of two different framework approaches: either KendoUI for a more Windows-like look and feel or AngularJS and Bootstrap for a more modern, responsive, design. More about these later.

The back end of the app will still consist mostly of C#, but we are going to use ASP.NET with the MVC pattern and construct a single page application (SPA) instead of a multi-page app. Single page apps differ from more traditional web apps in that they only have one web page (URL) that is refreshed dynamically. A "normal" web app switches from one page to another with each user action. SPAs rely on AJAX to allow the page to refresh without having to wait on a page load from the server (the "A" in AJAX stands for "asynchronous" which means stuff happens without the user having to wait). 

MV*

Our back end architecture is MVC and the front end is MVVM. Let's discuss. 

MVP/MVC/MVVM is a design pattern that's quite old but maybe was not adopted as widely as it should have been until more recently. The general idea is to separate the app logic from the UI. We do this using Models (thus the "M" in all of these patterns):

  • MVP: Model View Presentation (we don't use this)
  • MVC: Model View Controller (we use a Microsoft template for ASP.NET/MVC 4)
  • MVVM: Model View Viewmodel (we use this on the client side).

Hello MVC

 Let's take the classic Hello World example program to see how WebMAP creates an MVC architecture. Using C#, let's create a simple form (form1) with a few controls. See illustration:

form_diagram_Hello_World.jpg

The code is super simple: after creating the form in Visual Studio and setting some basic properties on the label, two textboxes, and one button. First we initialize the form, and then we handle the button click event:

private void button1_Click(object sender, EventArgs e)
{
txtOutput.Text = "Hello " + txtName.Text;
}

Notice in the classic C# code we are referencing UI elements directly...look at the designer file:

 private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox txtName;
private System.Windows.Forms.TextBox txtOutput;

But when we run the app through WebMAP and create our ASP.NET/MVC application code, we no longer reference or access UI elements directly. This is because we are going to create a model of the UI and work with the model.

For example, the code above where we handle the button click in Winforms now looks like this (from Form1.cs):

internal void button1_Click(object sender, System.EventArgs e)
{
ViewModel.txtOutput.Text = "Hello " + ViewModel.txtName.Text;
}

We still have our familiar txtOutput.Text and txtName.Text but they are being accessed as a "ViewModel". If we click F12 to go to the definition, we wind up in our Models folder at a file called Form1ViewModel.cs, where we see the following declaration:

public virtual UpgradeHelpers.BasicViewModels.TextBoxViewModel txtName { get; set; }

Digging into the helper classes we will find a class that lets us set the text on a viewmodel of a textbox. 

And fnally we have a controller folder, where we find this code:

public System.Web.Mvc.ActionResult button1_Click(Hello.ViewModels.Form1ViewModel viewFromClient, object eventSender)
{
   logic.ViewModel = viewFromClient;
   logic.button1_Click(null, null);
   return new UpgradeHelpers.WebMap.Server.AppChanges();

You can see the purpose of the controller is to manage the state changes on the server side.

Since the UX will actually be instantiated on a browser, we would expect some HTML and CSS to make it show up. Sure enough, we have two files:

  • Hello.Form1.html
  • Hello.Form1.css

Peeking into the HTML, we see inside a form element the following lines of code:

 <div>
<div data-width="284" data-height="261" name="Form1" data-title="Hello World" class="Hello_Form1" id="#= UniqueID #">
<form class="Form1">
<label id="label1" class=" label1">Please enter your name</label>
<input id="txtName" tabindex="3" class=" txtName" data-bind="value : txtName.Text" />
<button id="button1" tabindex="2" class=" button1" type="button" data-bind="events : { click : logic.button1_Click }, ">Then click here</button>
<input id="txtOutput" tabindex="4" class=" txtOutput" data-bind="value : txtOutput.Text" />
</form>
</div>
</div>

To recap, our simple Hello World app gets a facelift with WebMAP as a ASP.NET/MVC architecture, which includes a model, controller, and view. It also includes a lot of other stuff, but that will be saved for another blog post.

Topics: WebMAP3, ASP.NET/MVC