Click here to Skip to main content
Click here to Skip to main content
Articles » Web Development » ASP.NET » General » Downloads
 
Add your own
alternative version

Implementing Model-View-Presenter in ASP.NET

, 17 Nov 2007 CPOL
Three implementations of Model-View-Presenter in ASP.NET 2.0.
MVPSampleApp.zip
MVP.SampleApp
Lib
Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll
MySql.Data.dll
nunit.framework.dll
Rhino.Mocks.dll
Model
Data
Interfaces
Properties
Presentation
Presentation.Tests
Properties
Interfaces
Properties
SubSonic
ActiveRecord
Builder
CodeGeneration
Templates
CodeLanguage
Configuration
Controls
Calendar
lang
skin
active-bg.gif
calendar.gif
dark-bg.gif
hover-bg.gif
menuarrow.gif
normal-bg.gif
rowhover-bg.gif
status-bg.gif
title-bg.gif
today-bg.gif
Resources
DataProviders
Properties
Sql Tools
SubSonic.snk
Sugar
WebApp
App_Data
Views
SQL2000SampleDb.zip
SQL2000SampleDb.msi
using System;
using System.Text;
using System.Web.UI.WebControls;
using SubSonic;
using SubSonic.Utilities;
using System.Data;



namespace SubSonic
{
    public class ScaffoldCodeGenerator
    {
        #region Page Builders
        /// <summary>
        /// Generates the "In Front" code for an ASPX page
        /// </summary>
        /// <param name="providerName">Name of the DataProvider to use</param>
        /// <param name="tableName">Name of Table</param>
        /// <param name="pageFileName">The name of the ASPX page - like "Editor.aspx"</param>
        /// <param name="masterPage">The Master Page File, if any</param>
        /// <param name="languageType">Output language, i.e C# or that other one</param>
        /// <returns></returns>
        public static string GeneratePage(string providerName, string tableName, string pageFileName, string masterPage, LanguageType languageType)
        {
            //Grab the tableschema
            TableSchema.Table tbl = DataService.GetTableSchema(tableName, providerName);

            if (tbl.PrimaryKey == null)
            {
                return tableName + " does not contain a primary key. Primary keys are required for scaffold generation."; 
            }

            string pageTemplate = ResourceHelper.GetString(TemplateName.EDITOR);
                /*
                #PK# = Primary Key of the table
                #GRIDROWS# = all the rows in the GridView
                #EDITORROWS# = the rows inside the editor table
                #TABLENAME# = the name of the table
                */

                //this part's simple enough - just straight up text replacement
                pageTemplate = pageTemplate.Replace(TemplateVariable.TABLE_NAME, tbl.DisplayName);
                pageTemplate = pageTemplate.Replace(TemplateVariable.PK, tbl.PrimaryKey.ColumnName);
                pageTemplate = pageTemplate.Replace(TemplateVariable.PAGE_FILE, pageFileName);

                //now loop out the columns for each row of the table editor and grid
                StringBuilder gridRows = new StringBuilder();
                StringBuilder editorRows = new StringBuilder();

                foreach(TableSchema.TableColumn col in tbl.Columns)
                {
                    if(!col.IsPrimaryKey)
                    {
                        string control;
                        string properties = String.Empty;
                        control = GetControlText(typeof(BoundField).Name, null);
                        AddControlProperty(ref properties, "DataField", col.ColumnName);
                        AddControlProperty(ref properties, "HeaderText", Utility.ParseCamelToProper(col.ColumnName));
                        AddControlProperty(ref properties, "SortExpression", col.ColumnName);
                        ApplyControlProperties(ref control, properties);
                        gridRows.AppendLine(AddTabs(2) + control);
                        editorRows.AppendLine("\t\t<tr>" + Environment.NewLine + "\t\t\t<td class=\"scaffoldEditItemCaption\">" + Utility.ParseCamelToProper(col.ColumnName) + "</td>" + Environment.NewLine + "\t\t\t<td class=\"scaffoldEditItem\">" + GetEditControl(col) + "</td>" + Environment.NewLine + "\t\t</tr>");
                    }
                }

                pageTemplate = pageTemplate.Replace(TemplateVariable.EDITOR_ROWS, editorRows.ToString());
                pageTemplate = pageTemplate.Replace(TemplateVariable.GRID_ROWS, gridRows.ToString());


                //get the wrapper
                bool useMaster = !String.IsNullOrEmpty(masterPage);
                string wrapper = GetPageWrapper(useMaster);

                string jsBlock = CodeBlock.JS_BEGIN_SCRIPT + ResourceHelper.GetString(TemplateName.SCAFFOLD_DELETE_CONFIRMATION) + ResourceHelper.GetString(TemplateName.SCAFFOLD_CHARACTER_COUNTER) + CodeBlock.JS_END_SCRIPT;
                wrapper = wrapper.Replace(TemplateVariable.JAVASCRIPT_BLOCK, jsBlock);
                wrapper = wrapper.Replace(TemplateVariable.PAGE_CODE, pageTemplate.ToString());
                wrapper = wrapper.Replace(TemplateVariable.MASTER_PAGE, masterPage);
                wrapper = wrapper.Replace(TemplateVariable.TABLE_NAME, pageFileName.Replace(FileExtension.DOT_ASPX, String.Empty));

                //determine the language
                string codeFileExt = FileExtension.CS;
                if(languageType == LanguageType.VB)
                {
                    codeFileExt = FileExtension.VB;
                }
                wrapper = wrapper.Replace(TemplateVariable.LANGUAGE_EXTENSION, codeFileExt);

                return wrapper;

        }

        static string GetPageWrapper(bool useMaster)
        {
            string result;

            if (useMaster)
            {
                result = ResourceHelper.GetString(TemplateName.EDITOR_WRAPPER_MASTERPAGE);
            }
            else
            {
                result = ResourceHelper.GetString(TemplateName.EDITOR_WRAPPER);
            }
            return result;
        }

        private static string GetControlText(string controlType, string controlId)
        {
            if(!String.IsNullOrEmpty(controlId))
            {
                return "<asp:" + controlType + " ID=\"" + controlId + "\" runat=\"server\" " + TemplateVariable.CONTROL_PROPERTY + "></asp:" + controlType + ">";
            }
            else
            {
                return "<asp:" + controlType + " " + TemplateVariable.CONTROL_PROPERTY + "></asp:" + controlType + ">";
            }
        }

        private static string AddTabs(int count)
        {
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < count; i++)
            {
                sb.Append("\t");
            }
            return sb.ToString();
        }

        private static void AddControlProperty(ref string variableText, string propertyName, string propertyValue)
        {
            variableText += propertyName + "=\"" + propertyValue + "\" ";
        }

        private static void ApplyControlProperties(ref string controlText, string variableText)
        {
            controlText = controlText.Replace(TemplateVariable.CONTROL_PROPERTY, variableText.Trim());
        }

        private static string GetEditControl(TableSchema.TableColumn col)
        {
            string result;
            string variableText = String.Empty;
            string controlID = col.PropertyName;
            bool isTextBox = false;

            if(col.IsForeignKey)
            {
                result = GetControlText(typeof(DropDownList).Name, controlID);
            }
            else
            {
                switch(col.DataType)
                {
                    case DbType.Binary:
                    case DbType.Byte:
                        result = String.Empty;
                        break;
                    case DbType.Guid:
                    case DbType.AnsiString:
                    case DbType.String:
                    case DbType.StringFixedLength:
                    case DbType.Xml:
                    case DbType.Object:
                    case DbType.AnsiStringFixedLength:
                        if(Utility.IsMatch(col.ColumnName, ReservedColumnName.CREATED_BY) || Utility.IsMatch(col.ColumnName, ReservedColumnName.MODIFIED_BY))
                        {
                            result = GetControlText(typeof(Label).Name, controlID);
                        }
                        else
                        {
                            isTextBox = true;
                            result = GetControlText(typeof(TextBox).Name, controlID);
                            if(col.MaxLength > 250)
                            {
                                AddControlProperty(ref variableText, "TextMode", "MultiLine");
                                AddControlProperty(ref variableText, "Height", "100px");
                                AddControlProperty(ref variableText, "Width", "500px");
                            }
                        }
                        break;
                    case DbType.Date:
                    case DbType.Time:
                    case DbType.DateTime:
                        if(Utility.IsMatch(col.ColumnName, ReservedColumnName.MODIFIED_ON) || Utility.IsMatch(col.ColumnName, ReservedColumnName.CREATED_ON))
                        {
                            result = GetControlText(typeof(Label).Name, controlID);
                        }
                        else
                        {
                            result = GetControlText(typeof(Calendar).Name, controlID);
                        }
                        break;
                    case DbType.Int16:
                    case DbType.Int32:
                    case DbType.UInt16:
                    case DbType.Int64:
                    case DbType.UInt32:
                    case DbType.UInt64:
                    case DbType.VarNumeric:
                    case DbType.Single:
                    case DbType.Currency:
                    case DbType.Decimal:
                    case DbType.Double:
                        isTextBox = true;
                        result = GetControlText(typeof(TextBox).Name, controlID);
                        AddControlProperty(ref variableText, "Width", "50px");
                        if(col.DataType == DbType.Currency)
                        {
                            result = "$" + result;
                        }
                        break;
                    case DbType.Boolean:
                        bool isChecked = false;
                        if(Utility.IsMatch(col.ColumnName, ReservedColumnName.IS_ACTIVE))
                        {
                            isChecked = true;
                        }
                        result = GetControlText(typeof(CheckBox).Name, controlID);
                        AddControlProperty(ref variableText, ControlValueProperty.CHECK_BOX, isChecked.ToString());
                        break;
                    default:
                        isTextBox = true;
                        result = GetControlText(typeof(TextBox).Name, controlID);
                        break;
                }
            }
            if(isTextBox && col.MaxLength > 0)
            {
                AddControlProperty(ref variableText, "MaxLength", col.MaxLength.ToString());
            }
            ApplyControlProperties(ref result, variableText);
            return result;
        }
        #endregion


        #region Code Builder

        private static void CreatePropertySetter(ref string controlText, string controlId, string itemPropertyName, string controlPropertyName, bool toString, bool nullableType)
        {
            StringBuilder sb = new StringBuilder();
            if(nullableType)
            {
                sb.AppendLine("if(item." + itemPropertyName + ".HasValue)");
                sb.AppendLine(AddTabs(2) + "{");
                if(toString)
                {
                    sb.AppendLine(AddTabs(3) + controlId + "." + controlPropertyName + " = item." + itemPropertyName + ".Value.ToString();");
                }
                else
                {
                    sb.AppendLine(AddTabs(3) + controlId + "." + controlPropertyName + " = item." + itemPropertyName + ".Value;");
                }
                sb.AppendLine(AddTabs(2) + "}");
            }
            else
            {
                if (toString)
                {
                    sb.AppendLine(AddTabs(2) + controlId + "." + controlPropertyName + " = item." + itemPropertyName + ".ToString();");
                }
                else
                {
                    sb.AppendLine(AddTabs(2) + controlId + "." + controlPropertyName + " = item." + itemPropertyName + ";");
                }
            }
            controlText = sb.ToString();
        }

        static string GetControlValue(TableSchema.TableColumn col, string className)
        {
            StringBuilder result = new StringBuilder();
            string controlID = col.PropertyName;
            string propName = col.PropertyName;
            string converterType = (col.DataType == DbType.Currency || col.DataType == DbType.VarNumeric) ? "Decimal" : col.DataType.ToString();
            int tabIndent = 2;

            result.AppendLine(AddTabs(2) + "object val" + controlID + " = Utility.GetDefaultControlValue(" + className + ".Schema.GetColumn(\"" + propName + "\"), Page.FindControl(\"" + controlID + "\"), isAdd, false);");
            if(col.IsNullable)
            {
                result.AppendLine(AddTabs(2) + "if(val" + controlID + " == null)");
                result.AppendLine(AddTabs(2) + "{");
                result.AppendLine(AddTabs(3) + "item." + propName + " = null;");
                result.AppendLine(AddTabs(2) + "}");
                result.AppendLine(AddTabs(2) + "else");
                result.AppendLine(AddTabs(2) + "{");
                tabIndent++;
            }

            if (col.DataType != DbType.Guid)
            {
                result.AppendLine(AddTabs(tabIndent) + "item." + propName + " = Convert.To" + converterType + "(val" + controlID + ");");
            }
            else
            {
                result.AppendLine(AddTabs(tabIndent) + "item." + propName + " = new " + converterType + "(val" + controlID + ".ToString());");
            }

            if(col.IsNullable)
            {
                result.AppendLine(AddTabs(2) + "}");
            }
            return result.ToString();
        }

        static string SetControlValue(TableSchema.TableColumn col, string tableName)
        {
            string result = String.Empty;
            string propName = col.PropertyName;
            string controlID = col.PropertyName;
            bool isNullableType = (col.IsNullable && Utility.IsNullableDbType(col.DataType));

            if (col.IsForeignKey)
            {
                CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.DROP_DOWN_LIST, true, isNullableType);
            }
            else
            {
                
                switch(col.DataType)
                {
                    case DbType.Binary:
                    case DbType.Byte:
                        result = String.Empty;
                        break;
                    case DbType.DateTime:
                        CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.CALENDAR, false, isNullableType);
                        break;
                    case DbType.Boolean:
                        CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.CHECK_BOX, false, isNullableType);
                        break;
                    case DbType.Currency:
                    case DbType.VarNumeric:
                        CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.TEXT_BOX, true, isNullableType);
                        break;
                    case DbType.Int16:
                    case DbType.Int32:
                    case DbType.UInt16:
                    case DbType.Int64:
                    case DbType.UInt32:
                    case DbType.UInt64:
                    case DbType.Single:
                    case DbType.Decimal:
                    case DbType.Double:
                        CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.TEXT_BOX, true, isNullableType);
                        break;
                    case DbType.String:
                        CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.TEXT_BOX, false, isNullableType);
                        break;
                    default:
                        CreatePropertySetter(ref result, controlID, propName, ControlValueProperty.TEXT_BOX, true, isNullableType);
                        break;
                }
            }
            return AddTabs(2) + result;
        }

        /// <summary>
        /// Generates the CodeBehind for the Editor
        /// </summary>
        /// <param name="pageName">The name of the page - can end with ASPX if you like but it will be stripped</param>
        /// <param name="providerName">The Data provider to use</param>
        /// <param name="tableName">Name of the table</param>
        /// <param name="languageType">Output language, i.e C# or that other one</param>
        /// <returns></returns>
        public static string GenerateCode(string pageName, string providerName, string tableName, LanguageType languageType)
        {
            //Grab the tableschema
            TableSchema.Table tbl = DataService.GetTableSchema(tableName, providerName);
            string pageTemplate = ResourceHelper.GetString(TemplateName.EDITOR_CODE);
            /*
            #NAMESPACE_USING# = if there is more than one provider, include this Using statement
            #PAGEBINDLIST# = The list that binds the page to the object
            #BINDLIST# = List that binds the object to the page
            #DROPLIST# = Loads each dropdown
            #CLASSNAME# = the name of the class
            */

            //make sure the providers are loaded
            DataService.LoadProviders();

            //Set the Namespace
            string namespaceUsing;
            //if (DataService.Databases.Count > 1)
            //{
                //have to use the namespace
                namespaceUsing = "using " + Utility.CheckNamingRules(tbl.Provider) + ";";
            //}
            pageTemplate = pageTemplate.Replace(TemplateVariable.NAMESPACE_USING, namespaceUsing);

            //Set the class name
            string className = tbl.ClassName;
            pageTemplate = pageTemplate.Replace(TemplateVariable.CLASS_NAME, className);

            //Set the page class name
            string pageClass = pageName.Replace(FileExtension.DOT_ASPX, String.Empty);
            pageTemplate = pageTemplate.Replace(TemplateVariable.PAGE_CLASS, pageClass);


            //now loop out the columns for each row of the table editor and grid
            StringBuilder bindRows = new StringBuilder();
            StringBuilder pageBindRows = new StringBuilder();
            StringBuilder dropList = new StringBuilder();

            foreach (TableSchema.TableColumn col in tbl.Columns)
            {
                string controlName = col.PropertyName;

                if (!col.IsPrimaryKey)
                {
                    if(col.IsForeignKey)
                    {
                        //dropdown lists

                        TableSchema.Table FKTable = DataService.GetForeignKeyTable(col, tbl);
                        if(FKTable != null)
                        {
                            dropList.AppendLine(AddTabs(2) + "Query qry" + controlName + " = " + FKTable.ClassName + ".CreateQuery();");
                            dropList.AppendLine(AddTabs(2) + "qry" + controlName + ".OrderBy = OrderBy.Asc(\"" + FKTable.Columns[1].ColumnName + "\");");
                            dropList.AppendLine(AddTabs(2) + "Utility.LoadDropDown(" + controlName + ", " + "qry" + controlName + ".ExecuteReader(), true);");
                            if(col.IsNullable)
                            {
                                dropList.AppendLine(AddTabs(2) + controlName + ".Items.Insert(0, new ListItem(\"(Not Specified)\", String.Empty));");
                            }
                        }
                    }
                    pageBindRows.AppendLine(SetControlValue(col, className));
                    if(col.DataType != DbType.Binary && col.DataType != DbType.Byte)
                    {
                        bindRows.AppendLine(GetControlValue(col, className));
                    }
                }
            }
            
            pageTemplate = pageTemplate.Replace(TemplateVariable.BIND_LIST, bindRows.ToString());
            pageTemplate = pageTemplate.Replace(TemplateVariable.PAGE_BIND_LIST, pageBindRows.ToString());
            pageTemplate = pageTemplate.Replace(TemplateVariable.DROP_LIST, dropList.ToString());
            

            return pageTemplate;

        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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

Share

About the Author

Alex Mueller
Web Developer
United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.2 | Last Updated 17 Nov 2007
Article Copyright 2007 by Alex Mueller
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid