![]() |
Development Lifecycle »
Code Generation »
General
Intermediate
License: The GNU General Public License (GPL)
On the fly Code Generation with EvolutilityBy Olivier GiulieriA generic Web User Interface for CRUD applications generating all screens at run-time based on external metadata. It comes with sample applications for address book, memo pad, to do list, restaurants list, wine cellar, and database structure documentation that are easily customizable. |
VB, Javascript, XML, CSS, SQL, HTML, ASP.NET, Visual Studio, Dev
|
||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
IntroductionThis article presents a generic web user interface for CRUD applications implemented as a web control for ASP.net and SQL Server. Entirely metadata driven, this tool can adapt to different database structures. With it the user interface (fields titles, positions, visual groups, CSS classes) and its database mapping (tables, columns, stored procedures) are not defined in the code but in external metadata. It may behave like a to do list, an address book, a wine cellar, or any CRUD application you may want to build. It is ideal to quickly build functional components for database web applications or web site administration pages (which only need simple validation rules). This web control can be nested into any ASP.net page. It will generate at run-time all necessary web forms, manage user interaction, and database CRUD (create, read, update, delete) operations automatically. Because this tool feeds on metadata to change web form, structure, and volume, I called it "Evolutility" which in biology means "The faculty possessed by all substances capable of self-nourishment of manifesting the nutritive acts by changes of form, of volume, or of structure". |
To illustrate how simple CRUD applications can be used for more than administration pages, this article provides a demo project with several sample applications:
On one hand, from a developer point of view, these applications are similar because these use the same patterns and (if hand-coded) very similar code; on the other hand, from a user point of view, these are extremely different because these serve different purposes (like tracking lists of tasks or contacts, publishing a list of favorite restaurants, or managing a wine bottles inventory) and use very different sets of fields.
The "to do list" is the example used in my previous article on minimalist meta-model for CRUD applications so that the reader can get a hands on experience of metadata driven applications.
The "address book", "memo pad", "restaurant list", and "resources for the blind" are other simple CRUD applications provided to make the patterns obvious by repetition.
The "Database structure documentation" application is more interesting as it queries SQL Server metadata (system tables sysobjects and syscolumns) as if it where regular data to document the database automatically. It can be quite useful as it is always handy (published on the web) and always up-to-date because generated at run-time.
It can be used to documents tables:
as well as views, triggers, and stored procedures:
The last sample application is the "wine cellar" with a more complex UI using a larger number of fields grouped into panels and tabs:

and a master details for wine degustations.
All these sample applications are not running different compiled code but different instances of the same web control. Live demos available live at Evolutility.org.
A different kind of CRUD applications is discussed in my next article on Wizard and CRUD applications to build other CRUD applications.
Evolutility web control has built-in features for user identification, row level security, collaboration, and user comments. You may use them or bypass them with your own custom code (in the page nesting the control) for example to choose an XML file or another depending on the user.
At the component level (in the ASPX page)
The SecurityModel property of the control provides different ways of letting users view and update records:
In order to use Multiple_Users_RLS, and Multiple_Users_Sharing, the driving table must have a column called "UserID" (of type integer). Multiple_Users_Sharing also need a column called "Publish" (of type bit or integer).
The DBReadOnly property can prevent users from editing record, making the form Read-Only.
DBAllowDelete, DBAllowInsert, and DBAllowUpdate properties can use to allow or disallowed database functions like Delete, Insert and Update.
At the field level (in the metadata)
Individual Fields can be editable or Read-Only, using the readonly attribute of each field element.
Fields can be required or optional value (attributes required and optional).
In addition, you can choose to have different XML documents all together for different users.
User login is handled by Evolutility
|
When The stored procedure for user/password validation can be specified in the XML using the A sample stored procedure for user identification called "EvoDemoSP_Login" is provided with the samples. It can be modified to fit your specific needs. Sharing login information between different pages: Evolutility forms will share their login information with other Evolutility forms on the same web application which uses the same value for their |
|
Custom security
User identification:
You can use your own login screen for each page with custom code in the page forwarding to a login page if the user is not identified by your application.
Limiting access to specific fields for specific users:
Let's take an example: two users can look at product information, and one is allowed to see the price of products but the other is not. You can create 2 component definition (mapping to the same set of database tables), one including the product price, the other not. Then, use custom code in the page to identify the user and set bind Evolutility web control to one definition or the other.
Managing users
Managing users is as simple as any other entity; you just need to use Evolutility to map the users table.
You can create different pages as follow:
Any component can be set to allow users to post comments on records. This is done using the web control property UserComments. By default, comments are saved in the database table "Evol_Comment" but another table can be specified using the attribute dbtablecomments in the XML.
When allowing user comments, the number of comments on each record is displayed in lists:
Comments on record (if any) are displayed on the bottom of the page with a text box to enter new comments:
Most the tool flexibility comes from its metadata (described in my previous article on meta-model), but like all .net web controls it also has properties. Besides the standard WebControls properties inherited from the .net class, Evolutility provides the following properties.
AllowSorting: Allow search results to be sorted by columns. Setting it to false removes the up and down arrows for sorting records in the list header.
BackColorRowMouseOver: Determines color to highlight rows when the mouse cursor passes over.
CollapsiblePanels: Determines if user can show and hide panels.
DBAllowDelete: Properties used to allow or disallow specific database queries. DBReadOnly need to be False for these properties to take action.
DBAllowExport: Enables the export feature (for lists and single records).
DBAllowHelp: Will display the content of the help attribute of each field while in edit mode.
DBAllowInsert: Properties used to allow or disallow database record insertion on the driving table. DBReadOnly need to be False for these properties to take action.
DBAllowInsertDetails: Properties used to allow or disallow database record insertion on the details table.
DBAllowPrint: Specify whether or not the “Print” button should be displayed on the toolbar.
DBAllowSearch: Specify whether or not the "Search" and "Advanced Search" buttons should be displayed on the toolbar.
DBAllowSelections: Displays a "Selection” button on the toolbar to provide a list of custom queries. Need queries and query defined in the XML.
DBAllowUpdate: Properties used to allow or disallow modification of records on the driving table. DBReadOnly need to be False for these properties to take action.
DBAllowUpdateDetails: Properties used to allow or disallow in-place edition of the details table.
DBReadOnly: Make the page read only. Disables Add, Edit, and Delete on all records (toolbar buttons disappear when DBReadOnly is set to true).
DesignDisplayMode: Allows you to get a WYSIWYG display of any mode of the web form during design time.
DesignTabIndex: Allows you to get a WYSIWYG display of any tab of the Edit or View modes of the web form during design time.
DesignWebPath: Set the path to the XML directory at design-time. This path is concatenated to the XML filename.
DisplayMode (Read Only): Indicates the current display mode (View, Edit, List, Search, Advanced Search, or Selections).
DisplayModeStart: Mode in which Evolutility is displayed the first time the page is called.
ItemID (Read Only): ID of the current record.
Language: Localization of all text displayed in the control and date format. English and French are currently available. Possible values:
NavigationLinks: Show navigation links (for First, Previous, Next, and Last records) on the bottom of the page when editing or viewing records.
RowsPerPage: Number of rows displayed at one time in search results. This property is only available if a stored procedure for paging is specified in the XML of the application definition.
SecurityKey: Key to allow credential sharing among components.
SecurityModel: Manage users in 4 different ways with one of the following built-in security model:
ShowTitle: Determines the display of a header title.
SQLConnection: Connection string to the database. To avoid entering this property for every web control of your application, it can be set in the Web.config file of the application.
Text: Introduction text only displayed the first time the form is called.
Title: Application title.
ToolbarPosition: Position/display of the toolbar. Possible values:
UseCache: Enables or disables caching of lists of values. Setting it to true will improve performances.
UserComments: Allows users to post comments on specific records. Possible values:
UserID (Read Only): ID of the current user (0 if the user is not logged in or Evolutility is used in Single User mode).
VirtualPathDesigner: Sets the virtual path to app designer.
VirtualPathPictures: Sets the virtual path to the pictures used in fields.
VirtualPathToolbar: Sets the virtual path to the toolbar pictures.
XMLFile: Name of the XML file containing the metadata, it can be specified as an absolute path as "c:/EVOLUTILITY/XML/AddressBook.XML"; or as a relative path (recommended) as "XML/AddressBook.XML"; or with a wildcard <assemblypath> for the assembly path as "<assemblypath>AddressBook.XML" which allows the XML files to be in BIN directory with Evolutility.DLL.
Currently Evolutility provides one single event DBChange raised when a record is Inserted, Updated or Deleted.
The event argument DBChange specifies the Action (Insert, Update, or Delete) and ID where action is a string specifying the database query and ID is the primary key of the record to which the action was applied to.
Custom code in the page nesting the control can be triggered by the web control doing an action to the database. Here is a code sample to display the last database action in a label.
C#
private void Evolutility1_DBChange(object sender, Evolutility.Evolutility.DatabaseEventArgs e) { switch(e.Action) { case "INSERT": Label1.Text = String.Format("Record {0} added.", e.ID.ToString()); break; case "UPDATE": Label1.Text = String.Format("Record {0} updated.", e.ID.ToString()); break; case "DELETE": Label1.Text = String.Format("Record {0} deleted.", e.ID.ToString()); break; } }
VB.net
Private Sub evo1_DBChange(ByVal sender As System.Object, ByVal e As Evolutility.Evolutility.DatabaseEventArgs) Handles evo1.DBChange Select Case e.Action Case "INSERT" Label1.Text = "Record " & e.ID & " added to database" Case "UPDATE" Label1.Text = "Record " & e.ID & " updated" Case "DELETE" Label1.Text = "Record " & e.ID & " deleted" End Select End Sub
This "single event implementation" works but is quite limited. Adding better server events is now one of the top priorities for Evolutility. Now that the UI and database code are in place the next step is to make the tool more open and extendable.
When linking to a page which embeds the Evolutility web control, it is possible to alter the normal behavior of the control using request variables in the link. Possible examples are as follow:
Choosing a specific record
View the record of ID=5: MyPage.aspx?ID=5
Choosing a specific mode
To open the page in a specific mode, you can do the following:
Create a new record: MyPage.aspx?MODE=new
Edit the first record: MyPage.aspx?MODE=edit
Edit the record of ID=5: MyPage.aspx?MODE=edit&ID=5
Search page: MyPage.aspx?MODE=search
Advanced search page: MyPage.aspx?MODE=searchadv
Selections list: MyPage.aspx?MODE=selections
List of all records: MyPage.aspx?MODE=list
List result of the query "amex": MyPage.aspx?QUERY=amex
Every component is built and behaves the same way. One physical web page embeds Evolutility web control. Properties of the control indicate which metadata to get, what the privileges are (read, insert, edit, delete...), and a few other options.
When the user calls a page for the first time:
The user will execute an action on the page for example by clicking one of the control toolbar buttons.
To run the demo project and sample applications, follow these steps:
The easiest way to build applications using Evolutility is to start with an existing application and modify it to become the application you want. Just take any of the sample applications as a starting point, play with the XML by modifying the UI attributes or re-ordering fields. Then add or remove columns from the corresponding database table, and customize the XML accordingly.
An XML Schema Definition (XSD file) is included with the code to help you build and modify the metadata of the applications. The details of the XML syntax were discussed in my previous article on minimalist meta-model for CRUD applications or in more details on Evolutility.org.
Alternate ways to build applications with Evolutility are discussed in my next article on Wizard and CRUD applications to build other CRUD applications.
The project code is open source under Affero GPL v3 with dual licensing, hosted and updated at SourceForge. Enjoy... maybe improve it and contribute your code.
This kind of tools can save time while building applications, but it also makes maintenance and customizations much easier. It may even make them possible for non-technical users.
Also, in the case of commercial software, as (limited) customizations do not require re-compilation, it is ideal for customers, partners, and OEM because they will be able to customize or add screens without having access to the source code.
In addition, using a metadata driven approach to application development will reduce your code base to a fraction of what it usually is... and less code usually means less bugs.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 5 Sep 2008 Editor: Sean Ewington |
Copyright 2008 by Olivier Giulieri Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |