The Evolution of Application Architecture

When I started developing ASP.Net applications (.Net 1.1, around 2004), the world of application development looked simple:

Application connecting to a database and the “universe” (anything it needs to interface to)

(Before that, I developed in mainly Delphi, also in Oracle Forms or ASP/VB, and it always looked like this)

The web application would connect directly to the (SQL Server) database given the support of Visual Studio designers, query builders, etc., and the semi-automatic connection between parameters of database statements and the values of query string parameters, control properties, and so on.

Of course, the “simple” approach had some drawbacks, and I even created a tool called graspx to work around the drawbacks (rather than changing the approach, as I realized later), such as finding the SQL statements retrieving and writing data to figure out database dependencies.

The first step away from the direct application/database connection is to generate a code model based on the database model

Application using a code model representing the database model

Since the code model is derived from the database model, changes in the database model immediately cause the compilation to break if tables or fields are deleted.

However, the application is still monolithic, which restricts the ability to write unit and module tests for each piece of functionality (especially if you chose to develop ASP.Net web sites rather than web applications).

So, let’s separate the business logic from the user interface part (this can be done in classic ASP.Net as well, but it’s trickier. In ASP.Net MVC, you are forced strongly encourage to follow this pattern).

Application using a business layer implementing functionality, communicating with the database via a ORM, and interfacing to other environments using separate libraries.

The business layer may encapsulate various functionality, such as communicating with systems other than the database, handling different data, interfacing to other systems, and so on. We extract the interfacing code to separate assemblies for each system, and route the calls through the business layer assembly.

Usually, the front end application is not the single application accessing the database. You need to add a service that executes asynchronous operations, or write an import or export tool, allow batch processing and so on. These applications do not need the full functionality of the existing business layer (with all its dependencies on other systems), so we create a separate business layer assembly which only provides the data model that application requires:

Application using a business layer implementing functionality, communicating with the database via a ORM, and interfacing to other environments using separate libraries.

This architecture is not even restricted to a certain kind of applications (in my case, web applications with a certain database), you can also apply it to other scenarios:

CRM applications using a business layer implementing functionality, communicating with CRM database via the CRM data classes, and interfacing to other environments using separate libraries.

From my work on CRM projects, I noticed that these projects tend to look like charts 1 and 2. If you start out with the separation of layers and responsibilities, you can easily get a nice architecture, even if it is not obvious from the beginning.

Fixed layout, variable layout, or something completely different?

If you are working on a web application, sooner or later you come across the question of layouting your pages, and you’ll notice that there are a couple of (accepted) choices:

  • Variable (fluid, full-window) layout
  • Fixed layout (centered or not centered)
  • Elastic layout (what??)

Full-window layout is most likely the simplest and earliest web layout. If you create a plain HTML page, the contents will take up the whole width of the browser window. You’ll notice this if you browse pages from the early days of the web, and it’s immediately obvious that text written in long lines is very hard to read on a screen. (Try reading Wikipedia in a full-screen window on 1920 pixels – you soon feel the need to resize the browser window)

Given its age, it is surprising (or rather disturbing?) that the full-window layout is still promoted in current web development environments, as the ASP.Net MVC default page layout is defined in Site.css as

.page
{
    width: 90%;
    margin-left: auto;
    margin-right: auto;
}

meaning 5% of the window width as margin on the left and right side of the content. (All other measures in the CSS file are given in pixels (px) or relative to font height (em)).

In contrast, sites such as WordPress or online newspapers use a fixed layout. Fixed layout makes it easier to arrange the page elements in a grid independent of the browser’s window size. (Note that while most WordPress templates use fixed layout, the admin pages are full-screen with fixed and variable columns)

As a reaction to both the question fixed-vs-variable and the increasing multitude of web-enabled devices from HD monitors (or bigger) to smartphones, the latest trend in web design is called Responsive or Elastic.

Responsive layout is typically implemented using CSS3 Media Queries which allows the definition of page and page elements styles based on properties of the output format. They make it possible for a browser supporting media queries to apply the CSS styles definition based on window width, so that a text may be layouted full-screen on small displays, and in columns or fixed-width on larger displays.

For more discussion on the topic, visit Smashing UX Design (using responsive layout itself) or the User Experience StackExchange site. CSSGrid.net also implements a 1140px responsive layout.

Enjoy resizing 😉

Web.config Error in Build after Publish

If you publish an ASP.Net (MVC) application in VS 2010, you need to define a Target Location in the Publish… dialog.

VS then builds and publishes. Another manual build will result in the error message

Error 3 It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

For better entertainment, the file name that causes the error is displayed as “web.config” in the Error List window.

Right-click and select Copy will fill the clipboard with the real file path, which is

C:\path\to\project\obj\debug\package\packagetmp\web.config

which is a relict of the publishing process.

The solution is to delete everything from the obj\Debug and obj\Release directories (depending on your build configuration) and build again.

Update

Executing “Clean Solution” or “Clean Project” also solves the problem.

Removing Certain HTML Markup from String using Regex

Both ASP.Net and ASP.Net MVC frameworks by default protect your web application from accepting Form input data containing “<” characters, since this character may start a malicious HTML tag (i.e. HTML injection) if it is output unencoded by the web app.

If the input contains a “<“, ASP.Net will throw an exception:

A potentially dangerous Request.Form value was detected from the client

You can disable this validation routine in ASP.Net by adding the section

<configuration> 
  <system.web> 
    <pages validateRequest="false" /> 
  </system.web> 
</configuration>

to your web.config, and in ASP.Net MVC by adding the

[ValidateInput(false)]

attribute to the controller method.

Depending on your application, you now need to encode the data whenever it is output in an HTML page, or you need to check whether it really contains malicious tags, and remove them.

I created two regex’s for this purpose. The first one removes all attributes and values from HTML tags:

string html = "<p style=\"font-size: 2em\">hello. this is some html text</p>";
var rexTagAttrs = new Regex(@"<(\w+)\s.*?>");
html = rexTagAttrs.Replace(html, "<$1>");

The $1 evaluates to any tag name (\w+) the regular expression finds, and everything up to the next “>” is removed. This gets you rid of any custom formatting, such as created by rich text editors.

The next regex removes any HTML tags except those explicitly allowed:

var rexAllowedOnly = new Regex(@"(</?[^(p|ol|ul|li|span|i|b|br)]/?>)");
html = rexAllowedOnly.Replace(html, "");

The result of these two operations is HTML text that only contains the allowed tags which are save to display without encoding.

Validating a jQuery Dialog using jQuery Validate in ASP.Net

After I managed to create and display a jQuery dialog using the $().dialog() function, I wanted to replace my ad-hoc validation code with a “real” validation plugin, namely jQuery Validation. (naming consistency of jQuery plugins did not seem to matter until now, as there are several plugins with similar names in this area)

As much as I tried, the validator’s valid() would always return true, and debugging revealed that there were no elements to be checked, even though I had declared them in the validate() method.

Finally I came across this answer on SO, stating

the jQuery-UI dialog does not append to the form, it appends just before </body>, so the elements to validate are outside the <form></form> section

and suggesting the solution

$("#mydiv")
  .dialog("open")
  .parent()
  .appendTo(jQuery("form:first"));

Now it was obvious what’s happening: the dialog() function moves the <div> outside ASP.Net’s default form element (id=’aspnetForm’), directly under the <body> element.

Since I want to have several jQuery dialogs in my ASP.Net page, and cannot freely add <form> tags in the source code (especially not in .ascx and not in .aspx inside a MasterPage), I decided to create a <form> on the fly, and open the dialog inside the new form:

if (!$("#myForm").length) {
  $("<form>")
    .attr("id", "myForm")
    .attr("name", "myForm")
    .appendTo($("body")); 
} 

var d = $("#myDialog").dialog({ 
  autoOpen: false, 
  modal: true, 
  open: function () { 
    $("#myForm").validate({ ... }).resetForm(); 
  }, 
  buttons: [ 
    { id: "OK", 
      click: function() { 
        if (!$("#myForm").valid()) 
          return false; 
        ... process data ... 
        $("#myDialog").dialog("close"); 
      } 
    } 
  ] 
}); 

d.dialog("open")
  .parent().appendTo($("#myForm"));

Note that I added the call to resetForm() to clear errors from a previous execution of the dialog.

You can call the form validation using the .valid() method and simply leave the dialog open if a validation error occurred.

Have a look at the demos for help regarding HTML and CSS declarations.

Configuring JMeter for ASP.Net Sites

Comparing different web sites running the same ASP.Net application, my idea was to use JMeter to perform a couple of requests and display the execution times for the requests per site.

A web test is called Test Plan in JMeter, and in the most basic version looks like this:

The test plan has a Thread Group which defines how often a sequence of steps is performed, and how many threads are used to execute the sequence.

Use a HTTP Request Defaults configuration element to define server name, port number and other connection parameters.

Under the Simple Controller (under Logic Controllers) to contain the sequence of steps, consisting of HTTP Request or HTTP Request HTTPClient elements (under the Samplers menu). Each of them contains the URL Path (everything after the host name) and optionally a couple of parameters.

Next, add a couple of Listeners, such as Summary Report, View Results Tree and View Results in Table to display the requests’ performance data.

While this would be sufficient for non-ASP.Net web sites, ASP.Net requires a couple more elements.

First, the HTTP Cookie Manager is required to store the ASP.Net session cookie. Simply add it as config element.

Next, the various hidden variables of ASP.Net need to be parsed and posted. For example, a POST requires that the __VIEWSTATE variable is posted as well, otherwise ASP.Net would not be able to perform its magic.

To achieve this, we need a Regular Expression Extractor (post processor) to extract the value of the __VIEWSTATE variable in the original page:

Set the reference name to viewState (or any name you prefer and find reasonable), and the regular expression to

name="__VIEWSTATE" id="__VIEWSTATE" value="(.+?)"

In the login example below, we must first GET the login page, the RegEx extractor will retrieve the view state, which is then posted using the ${viewState} macro notation to pass its value on:

If you use the Ajax Control Toolkit, you may also need to pass the ScriptManager’s hidden value. Hit F12 in your browser, enable request logging (Net, All in Firefox; Network in Chrome), and find the posted value in the Request data.

Thanks to the pages that helped me with the information I needed: Technically Works, and a couple of answers on StackOverflow.

Goodbye, ScrewTurn Wiki

Earlier this month, Dario announced the end of ScrewTurn wiki. Despite a huge number of downloads (>300.000), the project was not a financial success (read: commercial licenses did not sell well enough).

My interest in ScrewTurn Wiki started when I enabled my database versioning and documentation application dbscript to generate database documentation both into ScrewTurn 2.0 and ScrewTurn 3.0. I even experimented with a Page Storage Provider for STW 2, but dropped it later because static generation performs better than dynamic generation (read: my page provider needed a lot of CPU).

The source code will be kept on Bitbucket, but everything else will be thrown into the memory hole. What a pity.

The comments mention another .Net-based OS wiki, Road Kill, but from a first look, the download numbers are low, and there seems to be a problem storing or displaying Unicode characters in articles. I’m not convinced.

Any other .Net wikis out there?

Thou Shalt Not Update on GET

Just ending a bug-fixing session of an ASP.Net project, we came across an interesting issue:

  • The customer wanted to avoid the “post again” message when pressing the browser’s back button (scenario sketched here)
  • The web application used templates file to inject HTML code into the pages as a means to allow localization and customization by the customer
  • Some of the post-back actions should be triggered by links or buttons contained in the template files
  • Posting by mechanisms of the ASP.Net framework and implementing the Post/Redirect/Get design pattern was therefore not possible
  • Manipulation of the web site’s shopping cart had therefore been implemented as links issuing GET requests

As a consequence, when you added a product and hit the Back button to view the product again, you added it once more to the shopping cart. Clearly, this is in violation of the accepted semantics of POST and GET requests:

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered “safe”.

Not good, greetings from The Spider of Doom.

To avoid major reorganization and rewrites of the existing pages, I took a shortcut using Javascript:

function PostAndRedirect(baseurl, params) {
  $.ajax({
    type: "POST",
    url: baseurl + params,
    success: function (xhr) {            // Success
      window.location.href = baseurl;
    },
    // If any AJAX errors, alert them
    error: function (xhr, ajaxOptions, thrownError) { 
      alert(xhr.status);
      alert(thrownError);
    }
  });
}

The function PostAndRedirect takes as parameter the target (most likely current) URL and the parameters to be posted. The POST is executed using the jquery.ajax() method. If the POST is successful, the function redirects to the URL (i.e. using a GET request).

Using this function, the browser never adds the POST request to its history, and therefore would not re-post upon pressing the Back button.

To invoke the Javascript function, simply add a Javascript URL as href value:

<a href="javascript:PostAndRedirect('SomeUrl.aspx', 
    '?cmd=add&productid=SomeProductId');">

Embedding Dynamic CSS in Asp.Net

There are many questions on SO on dynamically generating or applying CSS in ASP.Net or ASP.Net MVC.

Today I accidentally found a simple way to embed dynamic CSS in an aspx file:

in the markup, add runat=”server” to the <style> tag

<style type=”text/css”runat=”server”id=”htmlCss”></style>

This will generate a field of type HtmlGenericControl in the page.

In one of the page life-cycle events (Page_Load, Page_Init, etc), assign the literal CSS definition like this:

var css = @"
body
{
  background-color:#b0c4de;
}";
htmlCss.InnerHtml = css;

Lessons Learned Developing DNN Modules

Jumping into DNN development, here’s a couple of things I learned from developing my first modules.

Module Path

There are a couple of variables a module can derive its file system location (and thus relative URL paths) from:

ControlPath /dnn/DesktopModules/MyModule/
ModulePath /dnn/DesktopModules/MyModule/
Request.ApplicationPath /dnn
Request.CurrentExecutionFilePath /dnn/Default.aspx
ModuleConfiguration.ControlSrc DesktopModules/MyModule/View.ascx

If you need to reference files in the file system, or URLs relative to the module’s installation path, this statement

var IncludePath = ModuleConfiguration.ControlSrc
  .Replace("/View.ascx", "/");

gives you the module’s base directory.

Packaging

You can freely edit the module’s .dnn file to edit the components of the installation.

For example, if the module has no Edit or Settings dialog, remove Edit.ascx* and/or Settings.ascx* from the .dnn file under

component/
  desktopModule/
    moduleDefinitions/
      moduleDefinition/
        moduleControls

as you remove or exclude them from the DNN project (.csproj file).

If you do not have an Edit form, disable the registration of the Edit form in the ModuleActions getter of View.ascx.cs.

For layout definition and CSS classes in your Edit.ascx, see the HTML\EditHtml.ascx that comes with DNN.

View/Edit Mode

If your View.ascx should behave differently depending on whether it is displaying in View mode or Edit mode, use the following markup to distinguish the two modes:

<%  if (!DotNetNuke.Common.Globals.IsEditMode())  {   %>
      <!-- markup for edit mode -->
<%  } else { %>
      <!-- markup for view mode -->
<%  } %>

Closing Forms

To close a dialog, simply redirect to the current page:

protected void cmdUpdate_Click(object sender, EventArgs e)
{
  try
  {
    UpdateSettings();
    Response.Redirect(Globals.NavigateURL(), true);
  }
  catch (Exception exc)
  {
    Exceptions.ProcessModuleLoadException(this, exc);
  }
}

JavaScript

DNN uses a combination of JavaScript libraries

Embedding DNN pages in iframes

A typical DNN page contains menu, header, content panes, and a footer. The default skin of DNN6 is called DarkKnight and provides a page skin called „Host: DarkKnight – popUpSkin“ with just a single content pane and no headers, footers, borders, etc., and is thus perfect for embedding DNN pages inside an <iframe> either in the same DNN installation or from outside.

Display Time Range

You can set the period to display a page using the Start Date and End Date settings in the Advanced Settings section of the Module Settings.
Start and End Dates are only settable on a day level, there is no built-in way to display modules based on time of day.

Automatic Refresh

Automatic Refresh is supported on page level, but not on module level.

A little warning: the refresh interval is also active in Edit mode, so if you set the interval too short, you may not be able to set it to a longer interval directly in the page. You need to navigate to Host/Page Management and reset the refresh interval.