Tips and Tricks

Labels
AJAX(112) App Studio(7) Apple(1) Application Builder(245) Application Factory(207) ASP.NET(95) ASP.NET 3.5(45) ASP.NET Code Generator(72) ASP.NET Membership(28) Azure(18) Barcode(2) Barcodes(3) BLOB(18) Business Rules(1) Business Rules/Logic(140) BYOD(13) Caching(2) Calendar(5) Charts(29) Cloud(14) Cloud On Time(2) Cloud On Time for Windows 7(2) Code Generator(54) Collaboration(11) command line(1) Conflict Detection(1) Content Management System(12) COT Tools for Excel(26) CRUD(1) Custom Actions(1) Data Aquarium Framework(122) Data Sheet(9) Data Sources(22) Database Lookups(50) Deployment(22) Designer(177) Device(1) DotNetNuke(12) EASE(20) Email(6) Features(101) Firebird(1) Form Builder(14) Globalization and Localization(6) How To(1) Hypermedia(2) Inline Editing(1) Installation(5) JavaScript(20) Kiosk(1) Low Code(3) Mac(1) Many-To-Many(4) Maps(6) Master/Detail(36) Microservices(4) Mobile(63) Mode Builder(3) Model Builder(3) MySQL(10) Native Apps(5) News(18) OAuth(9) OAuth Scopes(1) OAuth2(13) Offline(20) Offline Apps(4) Offline Sync(5) Oracle(11) PKCE(2) Postgre SQL(1) PostgreSQL(2) PWA(2) QR codes(2) Rapid Application Development(5) Reading Pane(2) Release Notes(183) Reports(48) REST(29) RESTful(29) RESTful Workshop(15) RFID tags(1) SaaS(7) Security(81) SharePoint(12) SPA(6) SQL Anywhere(3) SQL Server(26) SSO(1) Stored Procedure(4) Teamwork(15) Tips and Tricks(87) Tools for Excel(2) Touch UI(93) Transactions(5) Tutorials(183) Universal Windows Platform(3) User Interface(338) Video Tutorial(37) Web 2.0(100) Web App Generator(101) Web Application Generator(607) Web Form Builder(40) Web.Config(9) Workflow(28)
Archive
Blog
Tips and Tricks
Friday, March 30, 2012PrintSubscribe
Virtualization Node Sets Made Easy

The workflow dashboard tutorial explains data controller virtualization.

Implementation of method VirtualizeController creates virtualization node sets to alter the data controller XML definition.

For example, the following snippet sorts the grid view grid1 in descending order of “Required Date” and rearranges its data fields by making “ShippedDate”, “EmployeeID”, and “ShipCity” appear first. The code snippet is written in Visual Basic.

If (IsTagged("OrdersShippedLate")) Then
    ' sort and rearrange 'grid1' by placing ShippedDate, EmployeeID, and ShipCity first
    NodeSet("view[@id='grid1']") _
        .Attr("sortExpression", "RequiredDate desc") _
        .Select("dataField") _
        .Arrange("@fieldName", "ShippedDate", "EmployeeID", "ShipCity")
End If

This is the data view without the virtualization node set:

The data controller view without the virtualization node set

This is the result of the virtualization node set executed at runtime:

Virtualization node set sorts the grid view grid1 in descending order of “Required Date” and rearranges its data fields by making “ShippedDate”, “EmployeeID”, and “ShipCity” appear first

Virtualization node sets alter the in-memory copy of the data controller XML definition. The in-memory copy is discarded as soon as the request from the data view has been processed.

This allows treating the entire application as a large toolkit full of building blocks. Each block may allow a maximum set of capabilities.

Developer uses virtualization node sets when implementing virtualization rules to change the building blocks. The data controller elements can be removed or changed in an arbitrary fashion. For example, the virtualization node set can be executed if a certain use case of the data controller is detected. The user identity may also trigger the virtualization node set execution.

Developers can also elect to add new capabilities to the data controller that were not defined at design time.

The example above uses the method BusinessRules.NodeSet() to create the virtualization node set. Chained calls of Attr(), Select(), and Arrange() methods are altering the data controller XML definition. Each method works on the collection of XML nodes produced by the previous call in the chain.

The basic virtualization node set methods allow selecting, deleting, arranging, and changing attributes and elements of the XML document. Selector expressions written in XPath are used as arguments of the basic methods.

The collection of named plugins is also available. The specially named methods of the virtualization node sets make the node sets much easier to understand. They do not require knowledge or understanding of XPath. Instead the methods are named after the familiar logical elements that developers are modifying in the Project Designer.

The following implementations of method VirtualizeController are written with the use of “plugin” methods instead of the basic ones. Basic methods are shown in the workflow dashboard tutorial. Each virtualization node set starts with the call to method NodeSet() without parameters and continues with calls of “named plugin” methods altering specific areas of the data controller.

C#:

protected override void VirtualizeController(string controllerName)
{
    if (controllerName == "Orders" && IsTagged("OrdersWaitingToShip", "OrdersShippedLate"))
    {
        // make the controller read-only by removing editing actions
        NodeSet().SelectActions("New", "Edit", "Delete", "Duplicate", "Import")
            .Delete();
        // delete all remaining actions in the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid")
            .SelectActions()
            .Delete();
        // add new 'Navigate' action to the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid")
            .CreateAction(
                "Navigate",
                "Orders.aspx?OrderID={OrderID}&_controller=Orders" +
                "&_commandName=Edit&_commandArgument=editForm1");
    }
    if (IsTagged("OrdersWaitingToShip"))
    {
        // sort grid1 and hide the 'ShippedDate' data field
        NodeSet().SelectView("grid1")
            .SetSortExpression("RequiredDate asc")
            .SelectDataField("ShippedDate")
                .Hide();
        // add data field 'ShipCountry' to 'grid1' view
        NodeSet().SelectView("grid1")
            .CreateDataField("ShipCountry");
    }
    if (IsTagged("OrdersShippedLate"))
        // sort and rearrange 'grid1' by placing ShippedDate, EmployeeID, and ShipCity first
        NodeSet().SelectView("grid1")
            .SetSortExpression("RequiredDate desc")
            .ArrangeDataFields("ShippedDate", "EmployeeID", "ShipCity");
}

Visual Basic:

Protected Overrides Sub VirtualizeController(controllerName As String)
    If (controllerName = "Orders" AndAlso IsTagged("OrdersWaitingToShip", "OrdersShippedLate")) Then
        ' make the controller read-only by removing editing actions
        NodeSet().SelectActions("New", "Edit", "Delete", "Duplicate", "Import") _
            .Delete()
        ' delete all remaining actions in the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid") _
            .SelectActions() _
            .Delete()
        ' add new 'Navigate' action to the 'Grid' scope 
        NodeSet().SelectActionGroups("Grid") _
            .CreateAction(
                "Navigate",
                "Orders.aspx?OrderID={OrderID}&_controller=Orders" +
                "&_commandName=Edit&_commandArgument=editForm1")
    End If
    If (IsTagged("OrdersWaitingToShip")) Then
        ' sort grid1 and hide the 'ShippedDate' data field
        NodeSet().SelectView("grid1") _
            .SetSortExpression("RequiredDate asc") _
            .SelectDataField("ShippedDate") _
                .Hide()
        ' add data field 'ShipCountry' to 'grid1' view
        NodeSet().SelectView("grid1") _
            .CreateDataField("ShipCountry")
    End If
    If (IsTagged("OrdersShippedLate")) Then
        ' sort and rearrange 'grid1' by placing ShippedDate, EmployeeID, and ShipCity first
        NodeSet().SelectView("grid1") _
            .SetSortExpression("RequiredDate desc") _
            .ArrangeDataFields("ShippedDate", "EmployeeID", "ShipCity")
    End If
End Sub

This is the effect of the virtualization node sets evaluated at runtime.

Effect of virtualization node sets on the data views

Thursday, March 1, 2012PrintSubscribe
View Filter Expressions

The alternative method of filtering is available in the data controller views. Property “View Filter” allows specifying an expression that will be embedded in the SQL statement composed by the application framework at runtime.

Suppose you want to filter a list of customers by a specific country.

Start the application generator and select your project, choose Design.

Locate the page Customers in Project Explorer, expand container1 and view1 nodes.

Double-click grid1 to active its properties.

Grid view "gird1" selected in Project Explorer

Enter the following expression in Filter Expression property of the Sort and Filter section.

Country = 'USA'

Sort and Filter section of a data controller view

Click OK button to save the changes and click Browse button on the tool bar. The generator will start the app in your default browser.

Navigate to Customers page and observe that only customers from the USA are displayed.

List of customers affected by the view filter Country = 'USA'

Select any customer by clicking on a link in the first column. The form view editForm1 will be activated.

Form view 'editForm1' inherits the filter from the last view 'grid1'. 

Notice that only customers from the USA are visible when you navigate between records in the form view with the help of navigation buttons.

Form view navigation buttons

The form view automatically inherits the value of Filter Expression from the last view that was presented to the user.

Static view filters work great when you need to present several alternative views of data. Users cannot remove the view filters and apply their own criteria on top of the view filter expressions.

View filter can also reference properties of the business rules class associated with the data controller of the view.

For example, you can define the following filter that contains a parameter.

Country = 'USA' and Region = @RegionName

If you generate the application and navigate to the Customers page then you will see the following exception:

View 'grid1' uses a filter with 'RegionName' parameter. Business rules class of the controller must provide a value for this parameter. The filter is defined as (Country = 'USA' and Region = @RegionName).

The application framework does not know how to determine the value of RegionName.

Right-click the data view view1 in the Project Explorer and choose Show Controller option.

"Show Controller" option in the context menu of data view node

Double-click Customers controller on the Controllers tab of Project Explorer.

"Customers" controller selected on the Controllers tab of Project Explorer

Enter CustomersBusinessRules in the Handler property of the controller and click save.

Definition of business rules class name

Exit the Designer and proceed to generate the project.

Select the project name on the start page of web application generator and click Develop.

Visual Studio or Visual Web Developer will start.

Open ~/App_Code/Rules/CustomersBusinessRules.cs(vb) class and enter the definition of RegionName read-only property.

C#:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MyCompany.Data;

namespace MyCompany.Rules
{
    public partial class CustomersBusinessRules : MyCompany.Data.BusinessRules
    {
        public string RegionName
        {
            get
            {
                return "OR";
            }
        }
    }
}

Visual Basic:

Imports MyCompany.Data
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Linq
Imports System.Xml
Imports System.Xml.XPath

Namespace MyCompany.Rules

    Partial Public Class CustomersBusinessRules
        Inherits MyCompany.Data.BusinessRules

        Public ReadOnly Property RegionName As String
            Get
                Return "OR"
            End Get
        End Property

    End Class
End Namespace

Navigate to the Customers page and observe that only customers from the state of Oregon are now visible.

List of customers affected by view filter (Country = 'USA' and Region = @RegionName)

Notice that the value returned by RegionName property of the business rules class does not become a part of SQL statement.  The application will compose a SELECT statement that incudes the view filter expression text with the resolved names of the data fields. An actual command parameter will be created . The property value will be assigned to the parameter value.

If you want to create a filtering expression as a dynamic fragment of SQL at runtime then consider using dynamic access control rules.

If more than one value needs to be passed to the view filter then consider changing the filter definition as follows (we have replaced “=” with “in”).

Country = 'USA' and Region in @RegionName

Change the property definition to return a list or an array of values.

C#:

public List<string> RegionName
{
    get
    {
        List<string> regions = new List<string>();
        regions.Add("OR");
        regions.Add("WA");
        return regions;
    }
}

Visual Basic:

Public ReadOnly Property RegionName As List(Of String)
    Get
        Dim regions As List(Of String) = New List(Of String)
        regions.Add("OR")
        regions.Add("WA")
        Return regions
    End Get
End Property

Customers from the states of Oregon and Washington are now available in the list.

List of customers filtered by array of (WA, OR)

The application framework will list a separate parameter in the composed SELECT statement for each value in the list returned by the RegionName property of the business rules class.  In our example the actual fragment of SQL will look as follows:

("Customers"."Country" = 'USA' and "Customers"."Region" in (@RegionName0,@RegionName1))

Saturday, February 25, 2012PrintSubscribe
Denormalization Field Map

A normalized database allows for efficient and economical data storage and retrieval. Business applications require displaying denormalized information to the users. The structure of the database is hidden from the user. End users can only relate to the business entities that they are accustomed to in the real world.

For example, consider the Order Details table in the Northwind sample database. The diagram below shows the normalized database schema. Normalization increases the performance and decrease the footprint of database records. On the other hand, this means that related data is stored in multiple tables, increasing the complexity of data presentation.

Code On Time automatically performs denormalization. It inserts several reference fields from master tables into each business object presented to the user. For example, in the “Reference Information" category on the Order Details screen, it includes Order Customer Company Name, Order Employee Last Name, and etc. These fields are not explicitly available in the Order Details table according to the database diagram.

DenormalizationProcess

The application generator detected direct and indirect foreign key relationships between Order Details and the rest of the tables in the above diagram, and has included reference fields from the linked master tables up to 3 levels. Only one master field is borrowed for inclusion into Order Details for each relationship. Usually, these fields are found either as 1) aliases for foreign key lookups of direct outgoing master relationships, such as Product Name or 2) read-only fields placed in the Reference Information category, such Order Ship Via Company Name.

image

Suppose we need to add the parent Employee’s FirstName and HomePhone to the Order Details forms.

Denormalization

Start the web application generator, click on the project name, and choose the Business Logic Layer option.

image

Switch to the Denormalization Field Map section, and enter the following field map:

dbo.Orders => dbo.Employees
FirstName
HomePhone

image

Press Finish to save your changes.

Click on the Refresh button. Select the Orders controller to ensure that it will reflect the new denormalization field map, and press Refresh.

image

Finally, press the Generate button.

When the website comes up, navigate to the Orders page. You will see that the fields have been added to the Reference Information category of this screen. Now you can find out the first name of the employee made the order and call them without having to look them up. All other pages that use the Orders data controller will also reflect these changes.

image

However, if you check the Order Details screen, the new reference fields are not there. You need to Refresh every relevant data controller in order for them to include the fields referenced in the Denormalization Field Map.

Click on the project name again, and press Refresh. Select the OrderDetails controller, and press Refresh.

image

When the website comes up again, you can see that the new reference fields FirstName and HomePhone have been added under Reference Information on the Order Details page.

image