Click here to Skip to main content
15,891,372 members
Articles / Web Development / ASP.NET

Implementing Model-View-Presenter in ASP.NET

Rate me:
Please Sign up or sign in to vote.
4.80/5 (27 votes)
17 Nov 2007CPOL12 min read 129.7K   2.7K   120  
Three implementations of Model-View-Presenter in ASP.NET 2.0.
<%@ Page Language="C#" %>
<%@ Import namespace="SubSonic.Utilities"%>
<%@ Import Namespace="SubSonic" %>

<%
	//The data we need
	string providerName = "#PROVIDER#";
	string tableName = "#TABLE#";
	TableSchema.Table tbl = DataService.GetSchema(tableName, providerName, TableType.Table);
	DataProvider provider = DataService.Providers[providerName];
    ICodeLanguage lang = new VBCodeLanguage();

	//The main vars we need
	TableSchema.TableColumnCollection cols = tbl.Columns;
	string className = tbl.ClassName;
	string thisPK = tbl.PrimaryKey.PropertyName;
	string varPK = tbl.PrimaryKey.ArgumentName;
	string varPKType = Utility.GetVariableType(tbl.PrimaryKey.DataType, tbl.PrimaryKey.IsNullable, lang);
%>

'Generated on <%=DateTime.Now.ToString() %> by <%=Environment.UserName %>
Namespace <%=provider.GeneratedNamespace %>
	''' <summary>
	''' Strongly-typed collection for the <%=className%> class.
	''' </summary>
	<Serializable> _
	Public Partial Class <%=className%>Collection 
	Inherits ActiveList(Of <%=className%>, <%=className%>Collection)
	    Public Sub New()
		End Sub

	End Class

	''' <summary>
	''' This is an ActiveRecord class which wraps the <%=tableName%> table.
	''' </summary>
	<Serializable> _
	Public Partial Class <%=className%> 
	Inherits ActiveRecord(Of <%=className%>)
		#Region "Default Settings"
		Protected Shared Sub SetSQLProps()
			GetTableSchema()
		End Sub

		#End Region
		
		#Region "Schema Accessor"
		Public Shared ReadOnly Property Schema() As TableSchema.Table
			Get
				If BaseSchema Is Nothing Then
					SetSQLProps()
				End If

				Return BaseSchema
			End Get

		End Property

		Private Shared Sub GetTableSchema()
			If (Not IsSchemaInitialized) Then
				'Schema declaration
				Dim schema As TableSchema.Table = New TableSchema.Table("<%=tableName%>", TableType.Table, DataService.GetInstance("<%=providerName%>"))
				schema.Columns = New TableSchema.TableColumnCollection()
				schema.SchemaName = "<%=tbl.SchemaName %>"
				'columns
				
                <%
                foreach(TableSchema.TableColumn col in cols)
                {
                    string varName = "col" +  col.ArgumentName;
                %>
                Dim <%=varName %> As TableSchema.TableColumn = New TableSchema.TableColumn(schema)
                <%=varName %>.ColumnName = "<%=col.ColumnName%>"
                <%=varName %>.DataType = DbType.<%=col.DataType %>
                <%=varName %>.MaxLength = <%=col.MaxLength %>
                <%=varName %>.AutoIncrement = <%=col.AutoIncrement.ToString().ToLower() %>
                <%=varName %>.IsNullable = <%=col.IsNullable.ToString().ToLower()%>
                <%=varName %>.IsPrimaryKey = <%=col.IsPrimaryKey.ToString().ToLower()%>
                <%=varName %>.IsForeignKey = <%=col.IsForeignKey.ToString().ToLower()%>
                <%=varName %>.IsReadOnly = <%= col.IsReadOnly.ToString().ToLower() %>
                <% if (!String.IsNullOrEmpty(col.DefaultSetting))
				   {					   
				%>
						<%=varName%>.DefaultSetting = "<%= col.DefaultSetting%>"
				<%
					}
                %>
                <%
					if(col.IsForeignKey)
					{
                %>
				<%=varName %>.ForeignKeyTableName = "<%= col.ForeignKeyTableName %>"
                <% } %>
                schema.Columns.Add(<%=varName%>)

                <%
                }
                %>

				BaseSchema = schema
				
				'add this schema to the provider
                'so we can query it later
                DataService.Providers("<%=providerName %>").AddSchema("<%=tableName%>",schema)

			End If

		End Sub

		#End Region
		
		#Region "Query Accessor"
		Public Shared Function CreateQuery() As Query
			Return New Query(Schema)
		End Function

		#End Region
		
		#Region ".ctors"
		Public Sub New()
			SetSQLProps()
			SetDefaults()
			
			MarkNew()
		End Sub
		
		Public Sub New(ByVal useDatabaseDefaults As Boolean)
			SetSQLProps()
			If useDatabaseDefaults = True Then
				ForceDefaults()
			End If
			MarkNew()
		End Sub

		Public Sub New(ByVal keyID As Object)
			SetSQLProps()
			SetDefaults()
			LoadByKey(keyID)
		End Sub

		Public Sub New(ByVal columnName As String, ByVal columnValue As Object)
			SetSQLProps()
			SetDefaults()
			LoadByParam(columnName,columnValue)
		End Sub

		#End Region
		#Region "Props"
		
		
        <%
			bool useNullables = tbl.Provider.GenerateNullableProperties;
			foreach(TableSchema.TableColumn col in cols)
			{
            string propName = col.PropertyName;
			string varType = Utility.GetVariableType(col.DataType, false, lang);
            string nullableVarType = Utility.GetVariableType(col.DataType, col.IsNullable, lang);

			if (useNullables || Utility.IsMatch(varType, nullableVarType))
			{
        %>  
        <XmlAttribute("<%=propName%>")> _
        Public Property <%=propName%> As <%=varType%> 
			Get
				Return GetColumnValue(Of <%= varType %>)("<%=col.ColumnName%>")
			End Get
		    
			Set
				SetColumnValue("<%=col.ColumnName%>", Value)
			End Set
		End Property
		
		
		<%
			}
			else
			{  
	    %>
		<XmlAttribute("<%=propName%>")> _
		Public Property <%=propName%> As <%=varType%> 
			Get
				Dim prop<%=propName%> As <%= nullableVarType%> = GetColumnValue(Of <%= nullableVarType%>)("<%=col.ColumnName%>")
				If Not prop<%=propName%>.HasValue Then
					Return <%= Utility.GetDefaultValue(col, lang)%>
				End If	
				Return prop<%=propName%>.Value
			End Get
		    
			Set
				SetColumnValue("<%=col.ColumnName%>", Value)
			End Set
		End Property

		<XmlIgnore()> _
		Public Property <%=propName%>HasValue As Boolean
			Get
				Dim prop<%=propName%> As <%= nullableVarType%> = GetColumnValue(Of <%= nullableVarType%>)("<%=col.ColumnName%>")
				If prop<%=propName%>.HasValue Then
					Return True
				End If
				Return False
			End Get
			
			Set
			  Dim prop<%=propName%> As <%= nullableVarType%> = GetColumnValue(Of <%= nullableVarType%>)("<%=col.ColumnName%>")
			  If Value = False Then
				 SetColumnValue("<%=col.ColumnName%>", Nothing)
			  Else If Value = True And prop<%=propName%>.HasValue = False Then
				 SetColumnValue("<%=col.ColumnName%>", <%= Utility.GetDefaultValue(col, lang)%>)
			  End If
		   End Set
		End Property
	    
		<% 
			}
        }
	    %>
		

		#End Region
		
		
			    
	    <%if (tbl.PrimaryKeyTables.Count > 0)
{%>
	    #Region "PrimaryKey Methods"
	    <%
    TableSchema.PrimaryKeyTableCollection pkTables = tbl.PrimaryKeyTables;
    if(pkTables != null)
    {
        ArrayList usedMethodNames = new ArrayList();
        foreach(TableSchema.PrimaryKeyTable pk in pkTables)
        {
            TableSchema.Table pkTbl = DataService.GetSchema(pk.TableName, providerName, TableType.Table);
            if(pkTbl.PrimaryKey != null && CodeService.ShouldGenerate(pkTbl))
            {
                string pkClass = pk.ClassName;
				string pkClassQualified = provider.GeneratedNamespace + "." + pkClass;
                string pkMethod = pk.ClassNamePlural;
				string pkColumn = pkTbl.GetColumn(pk.ColumnName).PropertyName;

                if(Utility.IsMatch(pkClass, pkMethod))
                {
                    pkMethod += "Records";
                }

                if(pk.ClassName == className)
                {
                    pkMethod = "Child" + pkMethod;
                }

                if(usedMethodNames.Contains(pkMethod))
                {
                    pkMethod += "From" + className;
                    if(usedMethodNames.Contains(pkMethod))
                    {
                        pkMethod += pkColumn;
                    }
                }

                usedMethodNames.Add(pkMethod);
                
                if(!String.IsNullOrEmpty(provider.RelatedTableLoadPrefix))
				{
					pkMethod = provider.RelatedTableLoadPrefix + pkMethod;
				}

                bool methodsNoLazyLoad = !provider.GenerateRelatedTablesAsProperties && !provider.GenerateLazyLoads;
                bool methodsLazyLoad = !provider.GenerateRelatedTablesAsProperties && provider.GenerateLazyLoads;
                bool propertiesNoLazyLoad = provider.GenerateRelatedTablesAsProperties && !provider.GenerateLazyLoads;
                bool propertiesLazyLoad = provider.GenerateRelatedTablesAsProperties && provider.GenerateLazyLoads;
				
                if(methodsNoLazyLoad)
                {
%>
			Public Function <%=pkMethod%>() As <%=pkClassQualified%>Collection 
	
				Return New <%=pkClassQualified%>Collection().Where(<%=pkTbl.ClassName%>.Columns.<%=pkColumn%>, <%=tbl.PrimaryKey.PropertyName%>).Load()
	
			End Function
			<%
                }
                else if(methodsLazyLoad)
                {
%>
			Dim col<%=pkMethod%> As <%=pkClassQualified%>Collection 
			Public Function <%=pkMethod%>() As <%=pkClassQualified%>Collection 
	
				If(col<%=pkMethod%> Is Nothing)
					col<%=pkMethod%> = New <%=pkClassQualified%>Collection().Where(<%=pkTbl.ClassName%>.Columns.<%=pkColumn%>, <%=tbl.PrimaryKey.PropertyName%>).Load()
				End If
				
				Return col<%=pkMethod%> 
				
			End Function
<%
                }
                else if(propertiesNoLazyLoad)
                {
%>
			Public ReadOnly Property <%=pkMethod%>() As <%=pkClassQualified%>Collection 

				Get
					Return New <%=pkClassQualified%>Collection().Where(<%=pkTbl.ClassName%>.Columns.<%=pkColumn%>, <%=tbl.PrimaryKey.PropertyName%>).Load()
				End Get
				
			End Property
<%
                }
                else if(propertiesLazyLoad)
                {
%>	
			Dim col<%=pkMethod%> As <%=pkClassQualified%>Collection 
			Public ReadOnly Property <%=pkMethod%>() As <%=pk.ClassName%>Collection 
				
				Get
					If(col<%=pkMethod%> Is Nothing)
						col<%=pkMethod%> = New <%=pkClassQualified%>Collection().Where(<%=pkTbl.ClassName%>.Columns.<%=pkColumn%>, <%=tbl.PrimaryKey.PropertyName%>).Load()
					End If
					
					Return col<%=pkMethod%>
				End Get
				
				Set(ByVal Value As <%=pk.ClassName%>Collection)
					col<%=pkMethod%> = Value
				End Set
				
			End Property
		<%
                }
            }
        }
    }
%>
		#End Region
		<%
}
%>

		
		
		
		
		
	    <%if (tbl.ForeignKeys.Count > 0) { %>
	    #Region "ForeignKey Methods"
	    <%
			TableSchema.ForeignKeyTableCollection fkTables = tbl.ForeignKeys;

			if (fkTables != null)
			{
				ArrayList usedPropertyNames = new ArrayList();
				foreach (TableSchema.ForeignKeyTable fk in tbl.ForeignKeys)
				{
					TableSchema.Table fkTbl = DataService.GetSchema(fk.TableName, providerName, TableType.Table);
					if (CodeService.ShouldGenerate(fkTbl))
					{
						string fkClass = fk.ClassName;
						string fkClassQualified = provider.GeneratedNamespace + "." + fkClass;
						string fkMethod = fk.ClassName;
						string fkID = tbl.GetColumn(fk.ColumnName).PropertyName;
						string fkColumnID = fk.ColumnName;


						//it's possible this table is "relatin to itself"
						//check to make sure the class names are not the same
						//if they are, use the fk columnName
						if (fk.ClassName == className)
						{
							fkMethod = "Parent" + fk.ClassName;
						}

						if (usedPropertyNames.Contains(fk.ClassName))
						{
							fkMethod += "To" + fkID;
						}

						if (tbl.GetColumn(fkMethod) != null)
						{
							fkMethod += "Record";
						}
	    %>

		''' <summary>
		''' Returns a <%=fkClass%> ActiveRecord object related to this <%=className%>
		''' </summary>

		Public Property <%=fkMethod%>() As <%=fkClassQualified%>
			Get
				Return <%=fkClassQualified%>.FetchByID(Me.<%=fkID%>)
			End Get

			Set
				SetColumnValue("<%=fkColumnID%>", Value.<%=fkTbl.PrimaryKey.PropertyName%>)
			End Set

		End Property

	    <%
			usedPropertyNames.Add(fk.ClassName);
		}
	}
}
	    %>
	    #End Region
	    <%} else {%>
	    'no foreign key tables defined (<%=tbl.ForeignKeys.Count.ToString() %>)
	    <%} %>
		




	    <%if (tbl.ManyToManys.Count > 0) { %>
	    #Region "Many To Many Helpers"
	    <%
			TableSchema.ManyToManyRelationshipCollection mm = tbl.ManyToManys;
			if (mm != null)
			{
				ArrayList usedConstraints = new ArrayList();
				foreach (TableSchema.ManyToManyRelationship m in mm)
				{
					TableSchema.Table fkSchema = DataService.GetSchema(m.ForeignTableName, providerName, TableType.Table);
					if (fkSchema != null && !usedConstraints.Contains(fkSchema.ClassName) && CodeService.ShouldGenerate(fkSchema) && CodeService.ShouldGenerate(m.MapTableName, m.Provider.Name))
					{
						usedConstraints.Add(fkSchema.ClassName);
						string fkClass = fkSchema.ClassName;
						string fkClassQualified = provider.GeneratedNamespace + "." + fkClass;
                
	    %>
	     
        Public Function Get<%=fkClass%>Collection() As <%=fkClassQualified%>Collection 
	        Return <%=className%>.Get<%=fkClass%>Collection(Me.<%=thisPK%>)
		End Function
		
        Public Shared Function Get<%=fkClass%>Collection(ByVal <%= varPK%> As <%= varPKType%>) As <%=fkClassQualified%>Collection
        
            Dim cmd As SubSonic.QueryCommand = New SubSonic.QueryCommand("SELECT * FROM <%=m.ForeignTableName%> INNER JOIN <%=m.MapTableName%> ON <%=m.ForeignTableName%>.<%=m.ForeignPrimaryKey%>=<%=m.MapTableName%>.<%=m.MapTableForeignTableKeyColumn%> WHERE <%=m.MapTableName%>.<%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name)
            
            cmd.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>, DbType.<%= DataService.GetSchema(m.MapTableName, providerName).GetColumn(m.MapTableLocalTableKeyColumn).DataType.ToString() %>)
            Dim rdr As IDataReader = SubSonic.DataService.GetReader(cmd)
            Dim coll As <%=fkClass%>Collection = New <%=fkClass%>Collection()
            coll.LoadAndCloseReader(rdr)

            Return coll
            
        End Function
        
        Public Shared Sub Save<%=fkClass%>Map(ByVal <%= varPK%> As <%= varPKType%>, ByVal items As <%=fkClass%>Collection)
        
            Dim coll As QueryCommandCollection = New SubSonic.QueryCommandCollection()

            'delete out the existing
            Dim cmdDel As QueryCommand = New QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name)
            cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)
            'add this in
            coll.Add(cmdDel)
			DataService.ExecuteTransaction(coll)

            For Each item As <%=fkClass%> In items 
				Dim var<%=m.ClassName%> As <%=m.ClassName%> = New <%= m.ClassName%>()
				var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)
				var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableForeignTableKeyColumn%>", item.GetPrimaryKeyValue())
				var<%=m.ClassName%>.Save()
			Next
			
        End Sub
        
        
        Public Shared Sub Save<%=fkClass%>Map(ByVal <%= varPK%> As <%= varPKType%>, ByVal itemList As System.Web.UI.WebControls.ListItemCollection)
        
            Dim coll As QueryCommandCollection = New SubSonic.QueryCommandCollection()

            'delete out the existing
            Dim cmdDel As QueryCommand = New QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name)
            cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)

            'add this in
            coll.Add(cmdDel)
            DataService.ExecuteTransaction(coll)

            For Each l As System.Web.UI.WebControls.ListItem In itemList 
            
                If l.Selected
				    
					Dim var<%=m.ClassName%> As <%=m.ClassName%> = New <%= m.ClassName%>()
					var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)
					var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableForeignTableKeyColumn%>", l.Value)
					var<%=m.ClassName%>.Save()
				    
                End If

            Next

        End Sub
        
        Public Shared Sub Save<%=fkClass%>Map(ByVal <%= varPK%> As <%= varPKType%>, ByVal itemList() As <%= varPKType%>) 
        
            Dim coll As QueryCommandCollection = New SubSonic.QueryCommandCollection()

            'delete out the existing
            Dim cmdDel As QueryCommand = New QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name)
            cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)

            'add this in
            coll.Add(cmdDel)
			DataService.ExecuteTransaction(coll)
            
            For Each item As <%= varPKType%> In itemList
            
                	Dim var<%=m.ClassName%> As <%=m.ClassName%> = New <%= m.ClassName%>()
					var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)
					var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableForeignTableKeyColumn%>", item)
					var<%=m.ClassName%>.Save()

            Next
            
        End Sub
        
		Public Shared Sub Delete<%=fkClass%>Map(ByVal <%= varPK%> As <%= varPKType%>) 
		
            Dim cmdDel As QueryCommand = New QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name)
            cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>)
            DataService.ExecuteQuery(cmdDel)

        End Sub
	      
	      
	      
	    <%
			}
		}
	}
	    %>
	    #End Region
	    <%} else {%>
	    'no ManyToMany tables defined (<%=tbl.ManyToManys.Count.ToString() %>)
	    <%} %>

		
		#Region "ObjectDataSource support"
		<%
            string insertArgs = string.Empty;
            string updateArgs = string.Empty;
			string seperator = ",";

			foreach (TableSchema.TableColumn col in cols)
			{
				string propName = col.ArgumentName;
				bool useNullType = useNullables ? col.IsNullable : false;
				string varType = Utility.GetVariableType(col.DataType, useNullType, lang);
				
				updateArgs += "ByVal " + propName + " As " + varType + seperator;
				if (!col.AutoIncrement)
				{
					insertArgs += "ByVal " + propName + " As " + varType + seperator;
				}
			}
			if (insertArgs.Length > 0)
				insertArgs = insertArgs.Remove(insertArgs.Length - seperator.Length, seperator.Length);
 			if (updateArgs.Length > 0)
				updateArgs = updateArgs.Remove(updateArgs.Length - seperator.Length, seperator.Length);
    	%>
		''' <summary>
		''' Inserts a record, can be used with the Object Data Source
		''' </summary>
		Public Shared Sub Insert(<%=insertArgs%>)
			Dim item As <%=className%> = New <%=className%>()
			<% 
		    foreach (TableSchema.TableColumn col in cols) {
				if (!col.AutoIncrement)
				{ 
            %>
            item.<%=col.PropertyName%> = <%=col.ArgumentName%>
            <%
                }
              } 
            %>
			If Not System.Web.HttpContext.Current Is Nothing Then
				item.Save(System.Web.HttpContext.Current.User.Identity.Name)
			Else
				item.Save(System.Threading.Thread.CurrentPrincipal.Identity.Name)
			End If
		End Sub

		''' <summary>
		''' Updates a record, can be used with the Object Data Source
		''' </summary>
		Public Shared Sub Update(<%=updateArgs%>)
			Dim item As <%=className%> = New <%=className%>()
		    <% 
		    foreach (TableSchema.TableColumn col in cols) 
			{
				%>
                item.<%=col.PropertyName%> = <%=col.ArgumentName%>
				<%
			} 
            %>
			item.IsNew = False
			If Not System.Web.HttpContext.Current Is Nothing Then
				item.Save(System.Web.HttpContext.Current.User.Identity.Name)
			Else
				item.Save(System.Threading.Thread.CurrentPrincipal.Identity.Name)
			End If
		End Sub

		#End Region
		#Region "Columns Struct"
		Public Structure Columns
			Dim x as Integer
			<% 
		    foreach (TableSchema.TableColumn col in cols) {
                string propName = col.PropertyName;
            %>
            Public Shared <%=propName%> As String = "<%=col.ColumnName%>"
            <%
              } 
            %>
		End Structure

		#End Region
	End Class

End Namespace

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)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions