5,427,303 members and growing! (14,695 online)
Email Password   helpLost your password?
Web Development » ASP.NET » General License: The Code Project Open License (CPOL)

Generic ASP.NET code-behind for CRUD pages

By Ricardo borges

Example of generic ASP.NET code-behind for CRUD of any NHibernate entity.
C# (C# 1.0, C# 2.0, C# 3.0, C#), .NET (.NET, .NET 2.0)

Posted: 4 Apr 2008
Updated: 4 Apr 2008
Views: 7,921
Bookmarked: 15 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
10 votes for this Article.
Popularity: 4.53 Rating: 4.53 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
1 vote, 33.3%
3
0 votes, 0.0%
4
2 votes, 66.7%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

CRUD is a basic functionality in most of existing applications, it means Create, Retrieve, Update and Delete. These actions will provide the needed tasks to persist a simple business entity.

The goal here is write a generic ASP.NET crud code-behind for any NHibernate entity.

Background

This article will not explain Object Relational Mapping (ORM), NHibernate, NSpring, Dependency Injection (IoC) but can be a good example of all this things, and a good example of how to create a n-tier web application.

The strategy applied to this feature can be used for other kind of data layer, such as Microsoft Enterprise Library Data Block. It is a little bit more complex, but it is possible.

Architecture

The architecture of this application is very important to allow the solution. It is not my design or creation, it is only the synthesis of good practices and some patterns. Let start with a class diagram, “one image is better than words”:

Arquitetura3.jpg

1) Data Layer: The data layer will be represented by data access objects (Dao). Each Dao class is responsible to persist one entity type.

2) Business Layer: This layer is represented by managers classes. Each entity must have a manager class for business rules. Each manager class has a Dao property for data access. The name of Manager must follow this rule: entityname + “Manager”.

Ex: The “Supplier” entity must have a SupplierManager in Business Layer.

1) Presentation Layer: As expected for this layer we have the ASP.NET web form showing formatted data to user. The name of web form page will indicate the functionality and the Type of entity to persist. The naming convention is important one more time:

Ex: One list page for “Supplier” entity must be: ListSupplier(aspx/cs);

One crud page for “Supplier” entity must be: CrudSupplier(aspx/cs);

This naming convention allows the GenericCrud component to know which entity is associated to the web form at runtime. So, we can create instances of the necessaries objects with reflection API for the CRUD feature.

Full view:

arquitetura.jpg

Using The Generic Crud Component

First, I will show you the code using the component for the “Supplier” crud page:

namespace WebExample
{
    public partial class CrudSupplier : Borges.Web.Page.GenericCrud
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

As you can see, the GenericCrud is a System.Web.UI.Page that implements all basics routines needed to persist the entity data. We just need to write a web form in aspx. How it is possible? There is no magic… just naming convention, generic Dao and object reflection.

But we must implement some simple rules in the aspx page:

1 – The ASP.NET web controls used to show the entity data must have the same ID of entity property.

2 – As I said before, the ASP.NET web form must be called “Crud” + entity name, ex: “CrudSupplier”.

3 – The Save or Update button must call the “SaveOrUpdate_Click” method, and the delete button must call “Delete_Click”.

After these simple rules in the aspx, the GenericCrud page will work for us…

Inside the GenericCrud

The component gets entity data by Id in the querystring called by the list entity page. We know the object to invoke for entity because the name of web form is indicating the entity name.

The component’s load event calls PrepareCrudPage() method, it gets the entity and manager names from URL and invokes the objects. At this moment the NSpring framework has a big important action. The NSpring will retrieve a singleton manager object by the manager name.

        public void PrepareCrudPage()
        {
            int start = url.IndexOf("Crud");
             int end = url.Substring(start).IndexOf(".");
             entityName = url.Substring(start, end).Replace("Crud", "");
             managerName = entityName + "Manager";
             manager = GetManager(managerName); 
         }
        public object GetManager(string managerName)
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
            return ctx.GetObject(managerName);



}

We have in the Spring.config file all the managers objects defined for singleton instances. After PrepareCrudPage(), the PopulateGrid() method is called to fill the web form. The CRUD page gets the id value in the query string, if it was sent by the list page. The same occurs for the “action” property.

        public void PopulateGrid(object id)
        {
            if (id == null)
                return;
            else if (id.Equals("")) return;


            object entity = GetEntityById(id);

            if (entity == null) return;

            FillFormByEntity(this.Page, entity, action);

        }


The PopulateGrid() gets the entity from business layer by GetEntityById() method, and gives it to FillFormByEntity() method.

        public object GetEntityById(object id)
        {
            if (!id.Equals(""))
            {
                Type type = manager.GetType();
                MethodInfo method = type.GetMethod("GetById");
                object entity = GetEntity(entityName);
                PropertyInfo Idproperty = (entity.GetType()).GetProperty("Id");
                entity = method.Invoke(manager, new Object[] { 
                    Converter.ChangeType(id.ToString(),Idproperty.PropertyType) });

               return entity;
            }
            else return null;


}

This is is a reflection routine to retrieve the entity object, and now the FillFormByEntity can be called. To fill the form, the method will get each property value from entity and set value for each web control.

Remind the naming convention… (property name == web control ID)

The GenericCrud doesn’t know the type of web control (it can be textbox, dropdown…), but the framework has the WebControlManager class to set any value for any kind of web control… just relax.

Now you know how GenericCrud can populate the form, and it is the same idea for save and update routines. In the inverse process, the entity data from web form will create a new entity state and will be saved. The unique detail here is that now we must know the type of entity property and make the type cast. The Borges.Util.Converter class makes it an easy task, even for Nullable types.

Look at these sequences diagrams for a more comprehensive explanation. Remember that SupplierManager object is instantiated by reflection:

Retrieve.jpg

save.jpg

Conclusion

We saw in this article some of OOP tools as code reuse by inheritance and reflection routines.

The GenericCrud and GenericList components can save some time of development, especially for a simple functionality. For more complex page, we can override the base methods and improve it. Of course, sometimes even CRUD pages needs some details that turns to difficult the generic component design.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ricardo borges


Ricardo Borges is graduated in Computer Science - UFBA, Brazil.


MCTS: .NET Framework 2.0 Web Applications
MCPD: Professional Web Developer

Contact: ricardoborges -> gmail <- com



"Computer science is no more about computers than astronomy is about telescopes." Dijkstra
Occupation: Software Developer
Company: ADN
Location: Brazil Brazil

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralFindcontrol in Master Pagememberstexavcar14:16 8 Jun '08  
GeneralRe: Findcontrol in Master PagememberRicardo borges8:42 9 Jun '08  
GeneralInterestingmemberRicky Wang16:06 19 May '08  
GeneralRe: InterestingmemberRicardo borges16:57 22 May '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 4 Apr 2008
Editor:
Copyright 2008 by Ricardo borges
Everything else Copyright © CodeProject, 1999-2008
Web07 | Advertise on the Code Project