ASP.NET 3.5

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
ASP.NET 3.5
Wednesday, February 25, 2009PrintSubscribe
Business Rules: RowBuilder Attribute

Latest update of Data Aquarium Framework introduces a new and much improved method of extending framework with custom business logic. You can take full advantage of declarative user interface of data controllers custom form templates, while having a significant control over data processing.

About Business Rules

ASP.NET development model makes it very easy for developers to mix user interface code and business logic code. It is just too tempting to write a few lines of a business rule that will be executed in response to a user interface control event. This leads to expensive maintenance.

We have put a significant effort into preventing such code blending from happening in applications built with Data Aquarium Framework. The first step was to introduce custom action handlers and data filters.

The new release builds on top of these two features and uses attribute-based approach to business rule development.

We will start review of business rules with RowBuilder attribute.

Sample Web application

Generate a sample Data Aquarium application from Northwind database.  Leave MyCompany as a default namespace. Make sure to request generation of business logic layer. We will use generated business objects to enhance our business rules whenever we need to access data. Note that if you generate your application with Membership support enabled then you will have to sign into your application in order to see any data presentation.

Open generated project in Visual Studio 2008 or Visual Web Developer 2008 and add a new class Class1 to ~/App_Code folder of your application. Our new class will inherit its base functionality from  BusinessRules class of MyCompany.Data namespace.

C#:

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

public class Class1: BusinessRules
{
    public Class1()
    {
    }
}

VB:

Imports Microsoft.VisualBasic
Imports MyCompany.Data

Public Class Class1
    Inherits BusinessRules

End Class

Open file ~/Controllers/Employees.xml and add attribute handler to dataController element.

<dataController name="Employees" conflictDetection="overwriteChanges" 
    label="Employees" xmlns="urn:schemas-codeontime-com:data-aquarium"
    handler="Class1">

This will hook your business rules to Employees data controller. Your business rules will be universally applied whenever a reference to a data controller is made. You business rules will be invoked when your application is utilizing DataViewExtender or ControllerDataSource, when you export data or create new employees in data lookups.

The same set of business rules can be applied to multiple data controllers.

Building New Rows

The first rule will be assigning employee ID of company's CEO to ReportsTo field of any new employee record.

Add the following method to Class1.

C#:

[RowBuilder("Employees", "createForm1", RowKind.New)]
protected void PrepareNewEmployeeRow()
{
    using (SqlText findCEO = new SqlText(
        "select EmployeeID, LastName from Employees where ReportsTo is null"))
    {
        if (findCEO.Read())
        {
            UpdateFieldValue("ReportsTo", findCEO["EmployeeID"]);
            UpdateFieldValue("ReportsToLastName", findCEO["LastName"]);
        }
    }
}

VB:

<RowBuilder("Employees", "createForm1", RowKind.New)> _
Protected Sub PrepareNewEmployeeRow()
    Using findCEO As SqlText = New SqlText( _
        "select EmployeeID, LastName from Employees where ReportsTo is null")
        If findCEO.Read() Then
            UpdateFieldValue("ReportsTo", findCEO("EmployeeID"))
            UpdateFieldValue("ReportsToLastName", findCEO("LastName"))
        End If
    End Using
End Sub

The protection level of this method is only important if you are planning to create hierarchies of business rule classes.

The name of the method plays no role at all. Name your business rules methods to reflect their purpose.

The method is automatically called whenever a new row is about to be returned to user interface components by Employees data controller. Typically this will happen when end user is creating a new record. There is also a restriction on the presentation view that will ensure method execution when createForm1 is presenting data. You can apply multiple RowBuilder attributes to the same method if the same business logic is executed by other controllers and/or views.

Use method UpdateFieldValue to assign any default values to fields of a new row.

Class SqlText is a utility provided with Data Aquarium Framework to give you a simple and efficient way of querying a database.

Run the sample application and start creating a new employee record. Scroll to the bottom of the screen to see the result of our effort.

image 

Next post will show how to manipulate fields of existing rows and demonstrate new look item style CheckBoxList.

The new lookup item style is featured in Membership user manager. Select any user and start editing a record. A menu of check boxes is presented to help you select user roles.

Monday, February 23, 2009PrintSubscribe
Starting DataViewExtender in "New" Mode

The latest update to Data Aquarium Framework introduces two new properties, StartCommandName and StartCommandArgument. You can use these properties to start a DataViewExtender instance in the desired mode by forcing it to execute a command just before the view is rendered in a web browser.

Quick Sample

Create a new page ~/NewProduct.aspx in a project generated with our ASP.NET Code Generator.

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" 
    AutoEventWireup="true" CodeFile="NewProduct.aspx.cs" Inherits="NewProduct" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Header1Placeholder" runat="Server">
    New Product
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="Header2Placeholder" runat="Server">
    Northwind
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="BodyPlaceholder" runat="Server">
    <div id="Products" runat="server" />
    <aquarium:DataViewExtender ID="ProductsExtender" runat="server" 
        TargetControlID="Products" 
        Controller="Products" View="createForm1" 
        StartCommandName="New" StartCommandArgument="createForm1" />
</asp:Content>

If you were to omit two last attributes in DataViewExtender markup then a read-only view of the first record of your data controller command is displayed. The framework treats all views the same way - there is no magic in "createForm1" name. The client engine will simply select the first record and present it in a specified view.

A client-side command "New" must be executed to force a display of a new record in createForm1. New properties will do the trick.

image

Client-Side State Machine

Another great feature available to developers is the client-side action state machine.

Run sample described above and then create a new record. As soon as a record is inserted you will be redirected to the "grid" view of all products. The same happens if you press Cancel button.

Suppose you want to use Cancel button to simply reset the form to the original "new" state. Also you want to rename button OK to Save and have it display a newly inserted record in "preview" mode that will lead to some fictitious step 2. A new button Save and New will create a new record and switch to the "new" mode right after a new record is created.

Open ~/Controllers/Products.aspx and change action group with scope "Form" as shown below.

<actionGroup scope="Form">
    <!-- modified actions -->
    <action whenLastCommandName="Select" whenLastCommandArgument="editForm1" 
            commandName="Edit" />
    <action whenLastCommandName="Select" whenLastCommandArgument="editForm1" 
            commandName="Delete" confirmation="Delete?" />
    <action whenLastCommandName="Select" whenLastCommandArgument="editForm1" 
            commandName="Cancel" headerText="Close" />
    <!-- no changes -->
    <action whenLastCommandName="Edit" commandName="Update" headerText="OK" />
    <action whenLastCommandName="Edit" commandName="Delete" confirmation="Delete?" />
    <action whenLastCommandName="Edit" commandName="Cancel" />
    <!-- modified actions -->
    <action whenLastCommandName="New" commandName="Insert" commandArgument="ShowProduct" 
            headerText="Save" />
    <action whenLastCommandName="New" commandName="Insert" commandArgument="SaveAndNew" 
            headerText="Save and New"/>
    <action whenLastCommandName="New" commandName="New" commandArgument="createForm1" 
            headerText="Cancel" confirmation="Do you want to reset this form?"/>
    <action whenLastCommandName="Insert" whenLastCommandArgument="ShowProduct" 
            commandName="Select" commandArgument="createForm1"/>
    <action whenLastCommandName="Insert" whenLastCommandArgument="SaveAndNew" 
            commandName="New" commandArgument="createForm1"/>
    <action whenLastCommandName="Select" whenLastCommandArgument="createForm1" 
            commandName="Navigate" commandArgument="~/Default.aspx?ProductID={ProductID}" 
            headerText="Continue to Step 2"/>
    <action whenLastCommandName="Select" whenLastCommandArgument="createForm1" 
            commandName="Cancel"/>
</actionGroup>

You probably noticed that new attribute whenLastCommandArgument is used to filter actions and complements attribute whenLastCommandName.

Action Insert creates a new record and in a case of success will try to select an action that is matched to the last command and argument. Pairs command/argument with values Insert/ShowProduct and Insert/SaveAndNew will trigger automatic execution of commands Select/createForm1 and New/createForm1.

Server-side actions Insert, Update, Delete, and any custom actions are forcing the state machine to execute if command has been successfully completed and server code did not request redirect or client script execution.

Here is how the screen looks when you refresh ~/NewProduct.aspx.

image

Enter details of a new product and click Save button. Product review form is presented.

image

If you click on Continue to Step 2 then you will be redirected to a URL that looks similar to the one below:

http://localhost:50689/NewFeatures/Default.aspx?ProductID=140

Hiding View Selector

The "orange" view selector at the top may spoil your view workflow ideas. Modify the content Content1 as shown below:

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
<style type="text/css">
    table.ViewSelector {
        display:none;
    }
</style>

The view selector will be hidden from users.

image

Thursday, November 27, 2008PrintSubscribe
Instant Details for Lookup Fields

Data Aquarium Framework provides powerful data lookup capabilities. We have extended them one step further by offering instant details for lookup fields.

Navigate to http://dev.codeontime.com/demo/nwblob, select Products in the drop down in the left top corner and select any product. Notice that an arrow is displayed next to Product Name field. The view component has detected that Product Name is defined as a lookup field and displayed an instant details link.

image

Click on the arrow and a Details page for Manjimup Dried Apples product will be presented.

image

Notice that instant details arrows are also displayed next to Supplier Company Name field and Category Name field. Follow category name link and the next level of details is presented.

image

You can rename the category, change description or upload a new image. As soon as you save the changes or click on Close button you will returned back to the product instant details. Click Close button on products instant details and you are back on the page with the order details.

In just a few clicks you can jump straight to the details of the lookup data and make necessary adjustments or research. The same details preview is available when you jump to item details displayed in RSS data feeds of your ASP.NET web application.

Continue to RSS Your Data