Xomega Architecture for ASP.NET Applications

Classic ASP.NET web applications mostly run on the web server, which processes HTTP requests from the client browser and then either serves static resources, such as images, JavaScript or CSS files, or generates and returns dynamic resources, which are mainly HTML that may be mixed with dynamically generated JavaScript code and CSS classes. That HTML is then rendered on the client browser, which also executes any scripts within the HTML. Those scripts may in turn issue asynchronous AJAX requests to the server, which would return the response either as HTML snippets or in some other format.

Most of the UI logic is implemented on the web server in the middle tier along with the business logic for the application. The middle tier can access the database or any other external services to read or update the data.

The following diagram demonstrates how the ASP.NET web application architecture is implemented using the default Xomega solution template.


Presentation Tier

The presentation tier that runs in the browser consists primarily in rendering the HTML response from the web server, executing any scripts contained therein and applying the stylesheets. The scripts typically provide client side validations of the user input, but may do some basic DOM manipulation or issue additional server side AJAX requests to call a web service on the server side or make a partial page request.

Middle Tier

Middle tier, which runs in the web server, has a layered structure with a Business Logic Layer, Service Layer and the Web Forms UI layer, which follows the Model-View-View Model (MVVM) development paradigm and in turn consists of Views, View Models and Code behind. All static resources such as HTML templates, JavaScript files, CSS and images are served by a standard Web Server like IIS.

The Views that represent the visual panels and controls get bound to the corresponding View Models that store the actual Model data for the view, the state and meta-data for that model data, such as whether this data is editable or required or the list of values it can accept, and also provide any functions that validate the data on the UI side or convert the data from one format to another, e.g. between the UI format and the internal values.

The actual UI logic is encapsulated in the Code behind that runs when the client sends GET or POST requests to the corresponding ASPX page (View) and acts as a Controller in the classic MVC approach. It instantiates a new View Model or retrieves the cached one from the current session and then binds it to the current View using Xomega Framework, which provides two-way binding. This means that whenever the user changes anything on the screen it will be automatically propagated to the model and vice versa – when the application changes the view model, it will be automatically reflected in the view that is bound to it.

The view models are implemented using Xomega Framework data object classes, which significantly simplifies both defining such data objects and its properties by providing all the plumbing for them such as validations, data conversion and formatting, lists of values and so forth, as well as binding view elements to those properties by implementing custom web bindings. These Xomega data objects may implement significant part of the UI behavior without any dependency on the web application, which means that you can reuse them in other types of clients such as desktop or Silverlight by simply binding them to a different XAML view.

Moreover, Xomega Framework data objects for the application are mostly automatically generated from the Xomega service model operations described in this document with ability to extend them in separate classes, so that the data objects could be regenerated any time the service model changes. The standard views with code behind for search and details pages can also be initially generated from the Xomega service model, which can help boost the development productivity as the developers could start with an 80% or so complete working view and then update it and add the remaining 20% of functionality.

The page’s Code behind handles any user actions on the server side and calls the services provided by the Service Layer to read the data for the data objects and save the user updates from the data objects into the database.

All service interfaces and structures for data contracts (also known as Data Transfer Objects or DTO) in the Service Layer are generated automatically from the Xomega service model. This allows providing alternative mock implementations of the services for testing purposes. The service implementation classes can also be initially generated from the Xomega service model, which speeds up the development process, but the developers need to implement any remaining service logic manually from that point on.

The service implementation classes use Entity Framework (EF) and LINQ to read the data from the database and persist the changes to the data. The Entity Data Model (EDM) is automatically generated from the Xomega object model and the classes for the corresponding entities are in turn generated from the EDM either by the built-in Visual Studio generator or by a T4 text template depending on whether you use the legacy Object Context or the latest DB context.

The generated entity classes can be extended to provide data validation, propagation and recalculation, which form the Business Logic Layer. This allows for all this entity functionality to be reused across multiple services and ensure data validity and integrity regardless of which service is updating this data. Business Logic Layer may also include a number of background tasks and services that run in the middle tier either on a scheduled basis or in response to external events.

Data Tier

The data tier (also called persistence tier) is implemented as a relational SQL server database that is hosted in its own database server. Most of the communication with the database from the middle tier can be handled automatically by the Entity Framework and LINQ queries. However, the middle tier may call the database directly to invoke a stored procedure or run a SQL query.

The SQL server database may also have its own internal logic implemented using T-SQL in the stored procedures or triggers that runs directly in the database.

MS Word templates for generating documents and reports

If you have ever developed technical MS Word documentation for a domain structure or an interface specification for a medium or large system, you may have wished that you were able to generate the whole document or a large part of it from some structured models, such as a database structure or formal service definition documents. Similarly, if you needed to create a report as a Microsoft Word document from some structured data set, it would require purchasing specialized reporting software, or a manual cut and paste exercise.

Before Microsoft Office 2007 all office documents were stored in a proprietary format, so generating such documents would require using special Office Interop assemblies to produce word documents. Luckily, Microsoft Office moved to the XML-based Open Office format starting from version 2007, which made it much more easy to both read and create office documents using standard XML technologies such as XSLT.

Obviously, generating all the necessary XML for Microsoft Word documents from scratch would be a lot of work and does not lend itself to customizing the way your document is generated. Therefore, it makes a whole lot more sense to create a template document that will serve as a base for the generated document, and have the generation process just replace certain placeholders with the values from your structured data. But how can you easily specify the placeholders in the word document in such a way that will give you maximum flexibility to generate the output you want?

Content placeholders in MS Word

One of the interesting features of the Microsoft Word documents is the ability to define Content Controls. Content controls provide a way to add user interface elements to the documents, restrict edits of some sections of the document, and also to data bind document elements to a specific data source. What matters though is that they provide an easy way for you to select any part of the document, wrap it in a content control, and tag it with some meta-information that would define how the contents should be processed to generate the output document.


This allows you to create and edit a document directly in Microsoft Word that will serve as a template, from which I can generate a full report using your data. In that template you can set up a new styles, headers, footers, cover page and any other static content as well as placeholders for dynamic content using these Content Controls. The content controls allow you to specify two free form properties: Title and Tag. Title will be shown in the document itself, so it is better to use it to specify the selector for the data, so that the designer of the template can easily see the data that will be displayed without pulling up the content control's properties dialog. The Tag field can be used then to specify the type of the placeholder.

To illustrate this let's see how you can define basic constructs, such as loops for outputting repeating contents, conditional contents and printing of simple values from your data source.

Defining repeating contents

This is useful when you have repeating contents and you want to output each item either as a separate section of the document or as a table. In either case, what you need to do is to select the section or the first row in your table that you want repeated, open the Developer tab in Word ribbon and click on the bold Aa button to wrap it in a Rich Text Content Control.

After that you click on the Properties button in the Developer tab and set the Tag value as 'loop' and the Title value to some selector string that identifies the data you want to repeat. If your data is in XML format or can be converted to such format, then you can use XPath expression here as the selector with some predefined parameter as the context item such as $ctx. See the picture below for an example.


Obviously, you will want to use additional content controls inside of your repeater control to output simple, conditional, or repeating contents unless you want to generate some static contents repeating over and over again.

Defining conditional content

You can use this when you want to output included contents only under a certain condition, or if you want to output different contents based in different conditions. Setting it up would be very similar as defining repeating contents described above.

You just need to select the contents that you need to be conditionally included, wrap it into a rich text content control by clicking the bold Aa button on the Developer tab, open up the Content Control Properties dialog and set the Tag and Title fields as follows.

To output the contents only if the specified condition is met enter 'if' into the Tag field, or 'elseif' if also none of the preceding if or elseif conditions should be met. Enter the condition into the Title field, which should evaluate to true for the contents to be included. Again, if your data source is XML then you can use XPath with $ctx as the context item.


Enter just 'else' in the Tag field without any Title to output the contents only if none of the preceding if or elseif conditions are met.

If you have multiple if / else groups on the same level then you can wrap each group into its own content control and set the tag to 'group' without specifying the title to group these conditions.

Outputting simple values

This is what you would use to output actual values from your data source, such as values in each column of a table or names of your sections. In order to output simple values you should also add a content control in your document, but this time around you would click non-bold Aa button in the Developer tab to insert a Plain Text Content Control as it will not require any nested controls.

After you open the content control properties, you should set the Tag to 'val' and Title to a string that evaluates to your value, which would be XPath if your data source is XML-based.


Technically, you can specify anything or nothing inside of your content control, since it will be replaced with the evaluated value, but in practicality you would want to put some sample data inside of that control to help the designer see what it would look like in the actual document.

Template example

To demonstrate this lets create a template for a simple price list with tables of product names and prices grouped into sections by product category. We will create a section with the title and a table with one row under the header, which will be wrapped into a loop content control and each cell will have a val content control for the product name and price respectively. The title will be also a val content control for the product category and we will wrap the entire section into another loop content control. Here is what it will look like in the Design Mode.

Below is a sample XML that conforms to the expected input structure.

<products>
  <pc Category="Mountain Bikes">
    <p Name="Mountain-100 Silver, 38" ListPrice="$3,399.99" />
    <p Name="Mountain-200 Black, 38" ListPrice="$2,294.99" />
    <p Name="Mountain-300 Black, 48" ListPrice="$1,079.99" />
    <p Name="Mountain-500 Black, 52" ListPrice="$539.99" />
  </pc>
  <pc Category="Road Bikes">
    <p Name="Road-150 Red, 62" ListPrice="$3,578.27" />
    <p Name="Road-650 Red, 52" ListPrice="$782.99" />
    <p Name="Road-250 Red, 58" ListPrice="$2,443.35" />
    <p Name="Road-750 Black, 52" ListPrice="$539.99" />
  </pc>
</products>

Generating documents with Xomega

In order to support transformation of such MS Word templates in Open Office format you can write a generic XSLT stylesheet that reads XML from the parts of the origin word template, applies it to your supplied XML data source, and packages the resulting XML into the corresponding part of the target document.

Xomega.Net for Visual Studio automatically comes with such a generic XSLT stylesheet, which it uses to create design documents for your domain and service models. You can, however, use it to generate documents from any custom XML. All you have to do is create your stylesheet that includes doc_common.xsl from Xomega and calls the generate-document with your XML as the parameter. You'll need to make sure that the values for DocumentTemplate and OutputPath parameters are specified either at run time or design time.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- import Xomega base generator -->
  <xsl:import href="doc_common.xsl"/>

  <xsl:param name="DocumentTemplate">PriceListTemplate.docx</xsl:param>
  <xsl:param name="OutputPath">BikePriceList.docx</xsl:param>

  <xsl:template match="/">

    <!-- call Xomega template to convert XML data to the output document -->
    <xsl:call-template name="generate-document">
      <xsl:with-param name="xmlData" select="."/>
    </xsl:call-template>

  </xsl:template>
</xsl:stylesheet>


If you run such a stylesheet with our sample price list data from above then you will get a document generated like this.

Conclusion

We have learned how to create document templates using Content Controls in MS Word and saw how you can generate documents from those templates and custom XML data source using generic Xomega stylesheet.

We would like to hear your thoughts, so please post your comments or contact us with any questions or feedback.