Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating a DotNetNuke® Module - For Absolute Beginners!

0.00/5 (No votes)
21 Jan 2007 4  
How to create a DotNetNuke® module using Visual Studio Express - for DotNetNuke version 4

Introduction

This article explains in detail the process of creating a DotNetNuke module.

Requirements

To use this tutorial, you need:

  1. Visual Studio Express (download here)
  2. SQL Server Express (download here)
  3. DotNetNuke Starter Kit 4.x (download here)

    Note: When you download it, it may change the file extension to ".zip". After downloading, change this to ".vsi", and then you can double-click on the file to install the templates.

Note: Do not attempt to create modules on a production installation of DotNetNuke; trust me, you will invariably screw up the installation and will have to restore the database or re-install.

Setup

  1. Install Visual Studio Express if you haven't already done so (download here).
  2. Install SQL Server Express if you haven't already done so (download here).
  3. Follow the directions here to install the DotNetNuke Starter Kit and to create a DotNetNuke website.

Creating_A_DNNModule/image002.jpg

Very important: Click once on the root directory in the Solution Explorer window. Doing so will ensure that the starter module code is created in the proper place.

Creating_A_DNNModule/image003.jpg

Select File from the toolbar, then New File:

Creating_A_DNNModule/image004.jpg

On the next menu, click once on DotNetNuke Module (under My Templates), select "Visual Basic" from the Language dropdown, type "GuestBook." in the Name box, and click Add.

Creating_A_DNNModule/image005.jpg

I interrupt this tutorial for an important warning:

Note: If the files DataProvider.vb, GuestBookController.vb, GuestBookInfo.vb, and SqlDataProvider.vb in the "ModuleName" directory are under "DesktopModules/App_Code" then they are in the wrong place.

Click on the "ModuleName" folder and drag it under the "App_Code" directory that is directly under the main root of the website. You will also have to move the "DesktopModules/ModuleName" folder and drag the "ModuleName" folder so it is under the "DesktopModules" folder that is directly under the main root of the website.

This is the correct way it should look:

Creating_A_DNNModule/image007.jpg

Creating_A_DNNModule/image008.jpg

Now back to the tutorial:

A very helpful help page comes up and instructs you to rename /App_Code/ModuleName to /App_Code/GuestBook, and rename /DesktopModules/ModuleName to /DesktopModules/GuestBook.

Creating_A_DNNModule/image009.jpg

Make the changes by right-clicking the folder name in the Solutions Explorer and selecting Rename from the menu. You have to do this twice. Once for the folder under "App_Code", and then for the folder under "DesktopModules".

Creating_A_DNNModule/image010.jpg

Creating_A_DNNModule/image011.jpg

Now, from the toolbar, select Build, then Build Web Site:

Creating_A_DNNModule/image017.jpg

The website should build without errors.

Creating_A_DNNModule/image018.jpg

In the Solution Explorer, right-click on "Default.aspx" and select Set As Start Page:

Creating_A_DNNModule/image019.jpg

From the toolbar, select Debug, then Start Without Debugging.

(You may wonder why I am not covering debugging. While creating this tutorial, I ran into permission problems on my own machine. They are easily fixed but I wanted to avoid any unneeded complexity. If you need help debugging, see this post.)

Creating_A_DNNModule/image020.jpg

Creating_A_DNNModule/image021.jpg

The website should now come up.

Creating_A_DNNModule/image022.gif

Click Login:

Creating_A_DNNModule/image023.jpg

Log in as "host". The password (if you haven't already changed it) is "dnnhost":

Creating_A_DNNModule/image024.jpg

Click on the HOST menu and select SQL.

Image 18

The form will display.

Image 19

Switch back to Visual Studio and in the Solution Explorer. Double-click on "01.00.00.SqlDataProvider" in the "DestopModules/GuestBook" directory so that it shows up in the main window.

Image 20

Click once on the page, then from the toolbar, select EDIT, then SELECT ALL (Ctrl +A).

Image 21

Then EDIT and COPY (Ctrl +C).

Image 22

Switch back to the DotNetNuke website and paste (Ctrl +V) the script you copied into the window, click the "Run as Script" box and click EXECUTE.

Image 23

From the HOST menu, select "Module Definitions".

Image 24

Click the small down arrow in the upper left hand corner of the Module Definitions menu and select "Create New Module".

Image 25

Select "GuestBook.dnn" in the Module Manifest drop-down and click Install.

Image 26

Under the Page Functions menu, click Add:

Creating_A_DNNModule/image031.jpg

In the Page Details menu:

  • Enter "Guest Book" for Page Name.
  • Enter "Guest Book" for Page Title.
  • Enter "Guest Book" for Description.
  • Click the View Page box next to All Users.

Then, click Update:

Creating_A_DNNModule/image032.jpg

From the Module drop-down, select "GuestBook":

Creating_A_DNNModule/image033.jpg

Then, click Add:

Creating_A_DNNModule/image034.jpg

If you get the "Object reference not set to an instance of an object" error, just click on the "Guest Book" link:

(However, if you are running DotNetNuke on a machine that is lower than a Pentium III with 512 KB RAM, then DotNetNuke will regularly throw this error).

Creating_A_DNNModule/image036.jpg

The module should now appear:

Creating_A_DNNModule/image037.jpg

The Guest Book Module

We will walk through the construction of the Guest Book module in these steps:

  • Data Access Layer (DAL) - We will create the tables, the stored procedures, and alter code in the "SqlDataProvider.vb" and "DataProvider.vb" files.
  • Business Logic Layer (BLL) - We will alter code in the "GuestBookController.vb" and "GuestBookInfo.vb" files.
  • Presentation Layer (UI) - We will alter code in the "ViewGuestBook.ascx", and in the other files in the "DesktopModules/GuestBook" directory.

Creating_A_DNNModule/image038.jpg

Data Access Layer (DAL)

To build the Data Access Layer, we will:

And that's it! It's actually not a lot of code to add to the "SqlDataProvider.vb" and "DataProvider.vb" files. Creating the tables and stored procedures is standard database programming that you are probably already used to.

Creating_A_DNNModule/image039.gif

From: "DotNetNuke Module Developers' Guide"

Copyright © 2003-2005 Perpetual Motion Interactive Systems, Inc. All Rights Reserved.

Connect to the Database

If you have created your DotNetNuke website using SQL Server 2005 Express, your database connection should already be set up for you. If you set it up using SQL Server 2000 or SQL Server 2005, then you may have to set it up.

To set up a connection to the SQL Server database, from the toolbar, select View, then Server Explorer.

Creating_A_DNNModule/image040.jpg

In the Server Explorer, right-click on Data Connections, and select "Add Connection":

Creating_A_DNNModule/image041.jpg

Fill in the connection information, and click OK.

Creating_A_DNNModule/image042.jpg

Delete the Sample Database Objects

You now need to delete the table and the stored procedures that the template created so that you can make new ones (that happen to use the same names) that the guestbook will use.

The connection will now show up in the Server Explorer. Click the plus next to the connection to expand it. Next, click the plus icon next to Tables to expand it.

Right click on the table "YourCompany_GuestBook" and select "Delete" and delete the table.

Note: At this point, the module will no longer work in your DotNetNuke web site. It will not work again until you have completed all the steps in this tutorial.

Creating_A_DNNModule/image043.jpg

Click the plus icon next to Stored Procedures to expand it. One at a time, right-click on the following stored procedures and select "Delete" to delete them. Remember, you have to delete them one at a time.

  • YourCompany_AddGuestBook
  • YourCompany_DeleteGuestBook
  • YourCompany_GetGuestBook
  • YourCompany_GetGuestBooks
  • YourCompany_UpdateGuestBook

Creating_A_DNNModule/image044.jpg

Create the Table

Log into the DotNetNuke website as Host (if you are not already logged in as Host), and from the Host menu, select SQL.

Creating_A_DNNModule/image045.jpg

Paste the following script in the box:

CREATE TABLE [dbo].[YourCompany_GuestBook](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ModuleID] [int] NULL,
[Name] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Email] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Message] [nvarchar](250) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[DateEntered] [datetime] NULL,
CONSTRAINT [PK_YourCompany_GuestBook] PRIMARY KEY CLUSTERED 
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

Do not select the "Run as Script" box, and click Execute.

(Note: This is a SQL 2005 script. It will not work in SQL 2000. For SQL 2000, you will have to create the table manually as explained in the next two steps.)

Creating_A_DNNModule/image046.jpg

Optionally, you can create the table in the table designer in Visual Web Developer. In the Server Explorer, right-click on Tables and select Add New Table:

Creating_A_DNNModule/image047.jpg

Design the table in the table designer using the graphics below. Make the "ID" column an "identity" column and also set it as the primary key. Save it as "YourCompany_GuestBook".

Creating_A_DNNModule/image048.jpg

Create the Stored Procedures

Log into the DotNetNuke website as Host (if you are not already logged in as Host), and from the Host menu, select SQL.

Creating_A_DNNModule/image045.jpg

Paste the following script in the box:

CREATE PROCEDURE {databaseOwner}
   [{objectQualifier}YourCompany_GuestBook_Delete] 
(
@ID int
)
AS
DELETE FROM {objectQualifier}YourCompany_GuestBook
WHERE (ID = @ID)
RETURN
GO
CREATE PROCEDURE {databaseOwner}
   [{objectQualifier}YourCompany_GuestBook_GetAll] 
(
@ModuleID int 
)
AS
SELECT ID, ModuleID, Name, Email, Message, DateEntered
FROM {objectQualifier}YourCompany_GuestBook
WHERE (ModuleID = @ModuleID)
order by DateEntered DESC
RETURN
GO
CREATE PROCEDURE {databaseOwner}
   [{objectQualifier}YourCompany_GuestBook_Insert] 
(
@ModuleID int,
@Name nvarchar(50),
@Email nvarchar(50),
@Message nvarchar(250)
)
AS
INSERT INTO {objectQualifier}YourCompany_GuestBook
(ModuleID, Name, Email, Message, DateEntered)
VALUES (@ModuleID,@Name,@Email,@Message,getdate())
RETURN
GO
CREATE PROCEDURE {databaseOwner}
   [{objectQualifier}YourCompany_GuestBook_Update] 
(
@ID int,
@Name nvarchar(50),
@Email nvarchar(50), 
@Message nvarchar(250),
@DateEntered datetime
)
AS
UPDATE {objectQualifier}YourCompany_GuestBook
SET Name = @Name, Email = @Email, 
    Message = @Message, DateEntered = @DateEntered
WHERE (ID = @ID)
RETURN
GO

Select the Run as Script box, and click Execute:

Creating_A_DNNModule/image049.jpg

Verify that the stored procedures have been created. Switch back to Visual Studio, and select View from the toolbar and Server Explorer:

Creating_A_DNNModule/image050.jpg

On the "Server Explorer" window, right-click on Stored Procedures and select Refresh:

Creating_A_DNNModule/image051.jpg

Scroll down the list of stored procedures and verify that these stored procedures have been created:

  • YourCompany_GuestBook_Delete
  • YourCompany_GuestBook_GetAll
  • YourCompany_GuestBook_Insert
  • YourCompany_GuestBook_Update

Creating_A_DNNModule/image052.jpg

Alter the "SqlDataProvider.vb" file. In Visual Studio, select View from the toolbar and "Solution Explorer":

Creating_A_DNNModule/image053.jpg

In the "Solution Explorer" window, expand the "GuestBook" directory under the "App_code" folder and double-click on the "SqlDataprovider.vb" file:

Creating_A_DNNModule/image054.jpg

Replace all the code with:

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports Microsoft.ApplicationBlocks.Data
Imports DotNetNuke.Common.Utilities
Imports DotNetNuke.Framework.Providers

Namespace YourCompany.Modules.GuestBook

Public Class SqlDataProvider Inherits DataProvider

    Private Const ProviderType As String = "data"
    Private Const ModuleQualifier As String = ""
    Private _providerConfiguration As _
      ProviderConfiguration = _
      ProviderConfiguration.GetProviderConfiguration(ProviderType)
    Private _connectionString As String
    Private _providerPath As String
    Private _objectQualifier As String
    Private _databaseOwner As String

    ' <summary>
    ' Constructs new SqlDataProvider instance
    ' </summary>
    Public Sub New()
        MyBase.New()
        'Read the configuration specific information for this provider
        Dim objProvider As Provider = CType(_providerConfiguration._
            Providers(_providerConfiguration.DefaultProvider), Provider)

        'Read the attributes for this provider
        If ((objProvider.Attributes("connectionStringName") <> "") _
                AndAlso (System.Configuration.ConfigurationManager._
                AppSettings(objProvider.Attributes(_
                "connectionStringName")) <> "")) Then
            connectionString = System.Configuration._
                ConfigurationManager.AppSettings(_
                objProvider.Attributes("connectionStringName"))
        Else
            _connectionString = _
              objProvider.Attributes("connectionString")
        End If

        _providerPath = objProvider.Attributes("providerPath")
        _objectQualifier = objProvider.Attributes("objectQualifier")

        If ((_objectQualifier <> "") _
               AndAlso (_objectQualifier.EndsWith("_") _
               = False)) Then
            _objectQualifier = (_objectQualifier + "_")
        End If

        _databaseOwner = objProvider.Attributes("databaseOwner")

        If ((_databaseOwner <> "") _
                   AndAlso (_databaseOwner.EndsWith(_
                   ".") = False)) Then
        _databaseOwner = (_databaseOwner + ".")
        End If
    End Sub

    ' <summary>
    ' Gets and sets the connection string
    ' </summary>
    Public ReadOnly Property ConnectionString() As String
        Get
            Return _connectionString
        End Get
    End Property
    
    ' <summary>
    ' Gets and sets the Provider path
    ' </summary>
    Public ReadOnly Property ProviderPath() As String
        Get
            Return _providerPath
        End Get
    End Property

    ' <summary>
    ' Gets and sets the Object qualifier
    ' </summary>
    Public ReadOnly Property ObjectQualifier() As String
        Get
            Return _objectQualifier
        End Get
    End Property

    ' <summary>
    ' Gets and sets the database owner
    ' </summary>
    Public ReadOnly Property DatabaseOwner() As String
        Get
            Return _databaseOwner
        End Get
    End Property

    ' --------------------------------------------------
    ' <summary>
    ' Gets the fully qualified name
    ' of the stored procedure
    ' </summary>
    ' <param name="name">The name
    ' of the stored procedure</param>
    ' <returns>The fully qualified name</returns>
    ' --------------------------------------------------
    Private Function GetFullyQualifiedName(ByVal _
                 name As String) As String
        Return (DatabaseOwner _
            + (ObjectQualifier _
            + (ModuleQualifier + name)))
    End Function
    
    ' --------------------------------------------------
    ' <summary>
    ' Gets the value for the field or DbNull
    ' if field has "null" value
    ' </summary>
    ' <param name="Field">The field to evaluate</param>
    ' <returns></returns>
    ' --------------------------------------------------
    Private Function GetNull(ByVal Field As Object) As Object
        Return Null.GetNull(Field, DBNull.Value)
    End Function

    Public Overrides Sub YourCompany_GuestBook_Insert(ByVal _
           ModuleId As Integer, ByVal Name As String, _
           ByVal Email As String, ByVal Message As String)
        SqlHelper.ExecuteNonQuery(ConnectionString, _
          GetFullyQualifiedName("YourCompany_GuestBook_Insert"), _
          ModuleId, Name, Email, Message)
    End Sub
    
    Public Overrides Sub _
           YourCompany_GuestBook_Delete(ByVal ID As Integer)
        SqlHelper.ExecuteNonQuery(ConnectionString, _
           GetFullyQualifiedName("YourCompany_GuestBook_Delete"), ID)
    End Sub
    
    Public Overrides Function YourCompany_GuestBook_GetAll _
           (ByVal ModuleId As Integer) As IDataReader
        Return CType(SqlHelper.ExecuteReader(ConnectionString, _
               GetFullyQualifiedName("YourCompany_GuestBook_GetAll"), _
               ModuleId), IDataReader)
    End Function
    
    Public Overrides Sub YourCompany_GuestBook_Update(ByVal ID _
           As Integer, ByVal Name As String, ByVal Email As _
           String, ByVal Message As String, _
           ByVal DateEntered As DateTime)
        SqlHelper.ExecuteNonQuery(ConnectionString, _
           GetFullyQualifiedName("YourCompany_GuestBook_Update"), _
           ID, Name, Email, Message, DateEntered)
    End Sub
End Class
End Namespace

You will notice that you will see errors such as:

"'YourCompany_GuestBook_Insert' cannot be declared 
  'Overrides' because it does not override a sub in a base class"

This is because the "DataProvider.vb" must indicate the methods that the "SqlDataProvider.vb" overrides. When we place those methods in the "DataProvider.vb" file, the errors will go away.

Creating_A_DNNModule/image055.jpg

Alter the "DataProvider.vb" file. In the Solution Explorer, in the "GuestBook" directory under the "App_code" folder, double-click on the "DataProvider.vb" file.

Creating_A_DNNModule/image056.jpg

Replace all the code with:

Imports System
Imports DotNetNuke
Imports System.Data
Imports DotNetNuke.Framework
Namespace YourCompany.Modules.GuestBook

Public MustInherit Class DataProvider
    ' singleton reference to the instantiated object
    Private Shared objProvider As DataProvider = Nothing

    ' constructor
    Shared Sub New()
    CreateProvider()
    End Sub

    ' dynamically create provider
    Private Shared Sub CreateProvider()
    objProvider = CType(Reflection.CreateObject("data", _
                  "YourCompany.Modules.GuestBook", _
                  ""), DataProvider)
    End Sub

    ' return the provider
    Public Shared Function Instance() As DataProvider
        Return objProvider
    End Function

    Public MustOverride Sub YourCompany_GuestBook_Insert(ByVal _
           ModuleId As Integer, ByVal Name As String, _
           ByVal Email As String, ByVal Message As String)
    Public MustOverride Function _
           YourCompany_GuestBook_GetAll(ByVal ModuleId _
           As Integer) As IDataReader
    Public MustOverride Sub YourCompany_GuestBook_Update(ByVal _
           ID As Integer, ByVal Name As String, _
           ByVal Email As String, ByVal Message _
           As String, ByVal DateEntered As DateTime)
    Public MustOverride Sub _
        YourCompany_GuestBook_Delete(ByVal ID As Integer)
End Class
End Namespace

Switch back to the "SqlDataprovider.vb" file and notice all the error messages are gone. Now would be a good time to save (Ctrl+Shift+S).

Creating_A_DNNModule/image057.jpg

Review

  • Data Access Layer (DAL) (Done)
  • Business Logic Layer (BLL)
  • Presentation Layer (UI)

We are done with the Data Access Layer. We will now program the Business Logic Layer. The Business Logic Layer will get done fast because it is only two files: a simple class file to hold our data, and a "controller" file that will fill the class file with data as well as handle inserting and deleting data.

The Business Logic Layer (BLL)

To build the Business Logic Layer, we will:

  • Alter "GuestBookInfo.vb"
  • Alter "GuestBookController.vb"

And that's it! This is the step that is usually the hardest for beginners to understand but is really not that complicated. However, ASP.NET 2.0 does provide a major reduction of code over the ASP.NET 1.1 version.

Alter the "GuestBookInfo.vb" File

In Visual Studio, select View from the toolbar and the "Solution Explorer":

Creating_A_DNNModule/image053.jpg

In the Solution Explorer window, expand the "GuestBook" directory under the "App_code" folder, and double-click on the "GuestBookInfo.vb" file:

Creating_A_DNNModule/image058.jpg

Replace every single line of code in the file with this code:

Imports System
Imports System.Configuration
Imports System.Data
Namespace YourCompany.Modules.GuestBook

Public Class GuestBookInfo
    Private _ModuleId As Integer
    Private _ID As Integer
    Private _Name As String
    Private _Email As String
    Private _Message As String
    Private _DateEntered As DateTime

    ' initialization
    Public Sub New()
      MyBase.New()
    End Sub

    ' <summary>
    ' Gets and sets the Module Id
    ' </summary>
    Public Property ModuleId() As Integer
     Get
      Return _ModuleId
     End Get
    Set(ByVal value As Integer)
      _ModuleId = value
     End Set
    End Property
    
    ' <summary>
    ' Gets and sets the Item ID
    ' </summary>
    Public Property ID() As Integer
     Get
      Return _ID
     End Get
     Set(ByVal value As Integer)
      _ID = value
     End Set
    End Property

    ' <summary>
    ' gets and sets the Name
    ' </summary>
    Public Property Name() As String
     Get
      Return _Name
     End Get
     Set(ByVal value As String)
      _Name = value
     End Set
    End Property

    ' <summary>
    ' Gets and sets the Email
    ' </summary>
    Public Property Email() As String
     Get
      Return _Email
     End Get
     Set(ByVal value As String)
      _Email = value
     End Set
    End Property

    ' <summary>
    ' Gets and sets the Message
    ' </summary>
    Public Property Message() As String
     Get
      Return _Message
     End Get
     Set(ByVal value As String)
      _Message = value
     End Set
    End Property

    ' <summary>
    ' Gets and sets the DateEntered
    ' </summary>
    Public Property DateEntered() As DateTime
     Get
      Return _DateEntered
     End Get
     Set(ByVal value As DateTime)
      _DateEntered = value
     End Set
    End Property
End Class
End Namespace

Creating_A_DNNModule/image059.jpg

Alter the "GuestBookController.vb" File

In Visual Studio, select View from the toolbar and the "Solution Explorer".

In the Solution Explorer window, expand the "GuestBook" directory under the "App_code" folder, and double-click on the "GuestBookController.vb" file:

Creating_A_DNNModule/image060.jpg

Replace every single line of code in the file with this code:

Imports System
Imports System.Collections.Generic
Imports System.Configuration
Imports System.ComponentModel
Imports System.Data
Imports System.Xml
Imports System.Web
Imports DotNetNuke
Imports DotNetNuke.Common
Imports DotNetNuke.Common.Utilities
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Services.Search

Namespace YourCompany.Modules.GuestBook
 Public Class GuestBookController

  <DataObjectMethod(DataObjectMethodType.Insert)> _
  Public Shared Sub GuestBook_Insert(_
         ByVal objTest As GuestBookInfo)
    DataProvider.Instance.YourCompany_GuestBook_Insert(_
      objTest.ModuleId, objTest.Name, _
      objTest.Email, objTest.Message)
  End Sub

  <DataObjectMethod(DataObjectMethodType.Delete)> _
  Public Shared Sub GuestBook_Delete(ByVal _
                objTest As GuestBookInfo)
    DataProvider.Instance._
      YourCompany_GuestBook_Delete(objTest.ID)
  End Sub

  <DataObjectMethod(DataObjectMethodType.Select)> _
  Public Shared Function GuestBook_GetAll(_
         ByVal ModuleId As Integer) _
         As List(Of GuestBookInfo)
    Return CBO.FillCollection(Of GuestBookInfo)_
           (DataProvider.Instance()._
           YourCompany_GuestBook_GetAll(ModuleId))
  End Function

  <DataObjectMethod(DataObjectMethodType.Update)> _
  Public Shared Sub GuestBook_Update(ByVal _
                    objTest As GuestBookInfo)
    DataProvider.Instance._
        YourCompany_GuestBook_Update(objTest.ID, _
        objTest.Name, objTest.Email, _
        objTest.Message, objTest.DateEntered)
  End Sub

 End Class
End Namespace

Creating_A_DNNModule/image061.jpg

Review

  • Data Access Layer (DAL) (Done)
  • Business Logic Layer (BLL) (Done)
  • Presentation Layer (UI)

We are done with the Business Logic Layer.

What did we just do?

The "GuestBookInfo.vb" was created. This is just a simple class file. It will hold the data.

Creating_A_DNNModule/image062.jpg

The "GuestBookController.vb" was created. This class has four methods:

  • GuestBook_Insert
    • Inserts items into the database. You pass a "GuestBookInfo" object to this method. The method then opens up the object and passes the individual parameters (module ID, name, email, message) to the "YourCompany_GuestBook_Insert" method in the DataProvider.vb file.
  • GuestBook_Delete
    • Deletes items from the database. You pass a "GuestBookInfo" object to this method. The method then opens up the object and passes the individual parameter (ID) to the "YourCompany_GuestBook_Delete" method in the DataProvider.vb file.
  • GuestBook_GetAll
    • Gets a recordset from the database. You pass a "ModuleId" parameter to this method. The method calls the "YourCompany_GuestBook_GetAll" method in the DataProvider.vb file and returns a "GuestBookInfo" object filled with data.
  • GuestBook_Update
    • Updates the database. You pass a "GuestBookInfo" object to this method. The method then opens up the object and passes the individual parameters (ID, module ID, name, email, message, date entered) to the "YourCompany_GuestBook_Update" method in the DataProvider.vb file.

Creating_A_DNNModule/image063.jpg

A Lot of Stuff Was Deleted

You may notice that a lot of code was deleted out of the "GuestBookController.vb" file. Some of this were the optional interfaces that handle exporting data and searching. These are interfaces that you will want to read about and implement in your modules. However, they are not required, and they are left out for simplicity.

A lot of code was eliminated by using code that is exclusive to ASP.NET 2.0 and incompatible with ASP.NET 1.1. ASP.NET 2.0 really saves you a lot of work and requires less code.

The Presentation Layer (UI)

From this point on, the files that need to be altered reside in the ".../DesktopModules/GuestBook" directory.

To build the Presentation Layer, we will:

  • Alter the "localization" (.resx) files.
  • Alter "controls" and their "code-behind" files:
    • EditGuestBook.ascx
    • Settings.ascx
    • ViewGuestBook.ascx

And that's it! The module will then be complete.

Creating_A_DNNModule/image064.jpg

Alter the Localization Files

Localization allows you to create labels that can have their text changed (for example, to change text from English to Spanish) by simply changing a "resource" file that has a ".resx" extension.

Double click on "EditGuestBook.ascx.resx" to open it.

Creating_A_DNNModule/image065.jpg

Change the content so it matches the picture below. The order does not matter. Save and close the file when done.

Creating_A_DNNModule/image066.jpg

Double click on "Settings.ascx.resx" to open it.

Creating_A_DNNModule/image067.jpg

Change the content so it matches the picture below. The order does not matter. Save and close the file when done.

Creating_A_DNNModule/image068.jpg

Double click on "ViewGuestBook.ascx.resx" to open it.

Creating_A_DNNModule/image069.jpg

Change the content so it matches the picture below. The order does not matter. Save and close the file when done.

Creating_A_DNNModule/image070.jpg

Alter the Controls

The module consists of three controls (and their "code-behind" files):

  • EditGuestBook.ascx
    • EditGuestBook.ascx.vb
  • Settings.ascx
    • Settings.ascx.vb
  • ViewGuestBook.ascx
    • ViewGuestBook.ascx.vb

Creating_A_DNNModule/image071.jpg

(A screen shot from the module definition that was created in the DotNetNuke site in the early step of the tutorial.)

Right-click on "EditGuestBook.ascx" and select "View Markup":

Creating_A_DNNModule/image072.jpg

Replace all the code with this code (save and close the file when done):

<%@ Control language="VB" 

     Inherits="YourCompany.Modules.GuestBook.EditGuestBook" 

     CodeFile="EditGuestBook.ascx.vb" 

     AutoEventWireup="true"%>
<%@ Register TagPrefix="dnn" TagName="Label" 

     Src="~/controls/LabelControl.ascx" %>
<dnn:label id="lblContent" runat="server" 

     controlname="lblContent" suffix=":">
</dnn:label>

<asp:ObjectDataSource ID="ObjectDataSource_Tasks" 

     runat="server" 

     DataObjectTypeName="YourCompany.Modules.
                         GuestBook.GuestBookInfo"

DeleteMethod="GuestBook_Delete" 

    InsertMethod="GuestBook_Insert" 

    OldValuesParameterFormatString="original_{0}"

    OnInit="Page_Load" SelectMethod="GuestBook_GetAll" 

    TypeName="YourCompany.Modules.GuestBook.GuestBookController"

    UpdateMethod="GuestBook_Update">
<SelectParameters>
  <asp:Parameter DefaultValue="00" Name="ModuleId" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>

<asp:GridView ID="GridView1" runat="server" 

    AllowPaging="True" AutoGenerateColumns="False" 

    DataSourceID="ObjectDataSource_Tasks" 

    DataKeyNames="ID">
<Columns>

<asp:CommandField ShowDeleteButton="True" 

        ShowEditButton="True" />
<asp:BoundField DataField="ID" 

        HeaderText="ID" Visible="False" />
<asp:BoundField DataField="ModuleID" 

        HeaderText="ModuleID" Visible="False" />
<asp:BoundField DataField="Name" 

        HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Message" 

        HeaderText="Message" SortExpression="Message" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:BoundField ApplyFormatInEditMode="True" 

        DataField="DateEntered" DataFormatString="{0:d}"

HeaderText="Date" HtmlEncode="False" 

        SortExpression="DateEntered" />
</Columns>
</asp:GridView>

Right-click on "Settings.ascx" and select "View Markup":

Creating_A_DNNModule/image073.jpg

Replace all the code with this code (save and close the file when done):

<%@ Control Language="VB" AutoEventWireup="false" 

       CodeFile="Settings.ascx.vb" 

       Inherits="YourCompany.Modules.GuestBook.Settings" %>
<%@ Register TagPrefix="dnn" TagName="Label" 

       Src="~/controls/LabelControl.ascx" %>

<dnn:label id="lblshowform" runat="server" 

       controlname="txtshowform" suffix=":">
</dnn:label>

<br />

<asp:DropDownList ID="DropDownList1" runat="server" 

       AutoPostBack="True" 

       nSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
  <asp:ListItem Selected="True">Yes</asp:ListItem>
  <asp:ListItem>No</asp:ListItem>
</asp:DropDownList>

Right-click on "ViewGuestBook.ascx" and select "View Markup":

Creating_A_DNNModule/image074.jpg

Replace all the code with this code (save and close the file when done):

<%@ Control Language="VB" 

     Inherits="YourCompany.Modules.GuestBook.ViewGuestBook" 

     CodeFile="ViewGuestBook.ascx.vb"

     AutoEventWireup="true" %>
<%@ Register TagPrefix="dnn" TagName="Label" 

     Src="~/controls/LabelControl.ascx" %>
<asp:ObjectDataSource ID="ObjectDataSource_Tasks" 

     runat="server" 

     DataObjectTypeName="YourCompany.Modules.
                         GuestBook.GuestBookInfo"

     DeleteMethod="GuestBook_Delete" 

     InsertMethod="GuestBook_Insert" 

     OldValuesParameterFormatString="original_{0}"

     SelectMethod="GuestBook_GetAll" 

     TypeName="YourCompany.Modules.
               GuestBook.GuestBookController"

     UpdateMethod="GuestBook_Update" 

     OnInit="Page_Load">
<SelectParameters>
  <asp:Parameter DefaultValue="00" 

          Name="ModuleId" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>

<asp:GridView ID="GridView1" runat="server" 

       DataSourceID="ObjectDataSource_Tasks"

       AutoGenerateColumns="False" 

       AllowPaging="True" HorizontalAlign="Center">
<Columns>
<asp:BoundField DataField="Name" 

       HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Message" 

       HeaderText="Message" 

       SortExpression="Message" />
<asp:BoundField ApplyFormatInEditMode="True" 

       DataField="DateEntered" DataFormatString="{0:d}"

HeaderText="Date" 

       SortExpression="DateEntered" 

       HtmlEncode="False" />
</Columns>
<EmptyDataTemplate>
There are no entries.
</EmptyDataTemplate>
</asp:GridView>
<br />
<center>
<dnn:Label ID="lblAddMessage" runat="server" 

       ControlName="lblAddMessage" Suffix=":">
</dnn:Label>
</center>
<br />
<asp:FormView ID="FormView1" runat="server" 

      DataSourceID="ObjectDataSource_Tasks" 

      DefaultMode="Insert" HorizontalAlign="Center">
<InsertItemTemplate>
<table cellpadding="2" cellspacing="5" 

          style="width: 50%" align="center">
<tr>
<td align="right" style="width: 4px">
<asp:Label ID="Label1" 

   runat="server" Text="Name"></asp:Label></td>
<td style="width: 100px">
<asp:TextBox ID="NameTextBox" runat="server" 

     Text='<%# Bind("Name") %>' 

     Width="264px"></asp:TextBox></td>
</tr>
<tr>
<td align="right" style="width: 4px; height: 23px">
<asp:Label ID="Label3" runat="server" 

         Text="Email"></asp:Label></td>
<td style="width: 100px; height: 23px">
<asp:TextBox ID="EmailTextBox" runat="server" 

        Text='<%# Bind("Email") %>' 

        Width="264px"></asp:TextBox></td>
</tr>
<tr>
<td align="right" style="width: 4px; height: 21px">
<asp:Label ID="Label2" runat="server" 

        Text="Message"></asp:Label></td>
<td style="width: 100px; height: 21px">
<asp:TextBox ID="MessageTextBox" 

        runat="server" EnableViewState="False" 

        MaxLength="250" Rows="2" 

        Text='<%# Bind("Message") %>' 

        TextMode="MultiLine" 

        Width="264px"></asp:TextBox></td>
</tr>
<tr>
<td align="right" colspan="2" style="height: 21px">
<asp:Button ID="InsertButton" runat="server" 

        Text="Submit" CommandName="Insert" /></td>
</tr>
</table>
<br />

</InsertItemTemplate>
</asp:FormView>

Right-click on "EditGuestBook.ascx" and select "View Code":

Creating_A_DNNModule/image075.jpg

Replace all the code with this code (save and close the file when done.):

Imports DotNetNuke
Imports System.Web.UI
Imports System.Collections.Generic
Imports System.Reflection
Imports DotNetNuke.Entities.Modules

Namespace YourCompany.Modules.GuestBook
Partial Class EditGuestBook Inherits PortalModuleBase
    Protected Sub Page_Load(ByVal sender As Object, _
              ByVal e As System.EventArgs)
        Try
        Catch exc As Exception
            Exceptions.ProcessModuleLoadException(Me, exc)
        End Try
    End Sub

    Protected Sub SetModuleId(ByVal sender As Object, _
              ByVal e As System.Web.UI.WebControls._
              ObjectDataSourceSelectingEventArgs) _
              Handles ObjectDataSource_Tasks.Selecting
        e.InputParameters("ModuleId") = ModuleId.ToString
    End Sub
End Class
End Namespace

Right-click on "Settings.ascx" and select "View Code":

Creating_A_DNNModule/image076.jpg

Replace all the code with this code (save and close the file when done):

Imports System
Imports System.Web.UI
Imports DotNetNuke
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Services.Exceptions
Namespace YourCompany.Modules.GuestBook

Partial Class Settings Inherits ModuleSettingsBase
    Public Overrides Sub LoadSettings()
        Try
            If (Page.IsPostBack = False) Then
                If (Not (CType(TabModuleSettings(_
                       "showform"), _
                       String)) Is Nothing) Then
                    Me.DropDownList1.SelectedValue_
                       = CType(TabModuleSettings(_
                       "showform"), String)
                End If
            End If
        Catch exc As Exception
            Exceptions.ProcessModuleLoadException(Me, exc)
        End Try
    End Sub

    Protected Sub DropDownList1_SelectedIndexChanged(ByVal_
           sender As Object, ByVal e As EventArgs)
        Dim objModules As ModuleController = _
                 New ModuleController

        If (Me.DropDownList1.SelectedValue = "Yes") Then
            objModules.UpdateTabModuleSetting(_
                 TabModuleId, "showform", "Yes")
        Else
            objModules.UpdateTabModuleSetting(_
               TabModuleId, "showform", "No")
        End If
    End Sub
End Class
End Namespace

Right-click on "ViewGuestBook.ascx" and select "View Code":

Replace all the code with this code (save and close the file when done):

Creating_A_DNNModule/image077.jpg

Imports DotNetNuke
Imports System.Web.UI
Imports System.Collections.Generic
Imports System.Reflection
Imports DotNetNuke.Entities.Modules
Namespace YourCompany.Modules.GuestBook

Partial Class ViewGuestBook
  Inherits Entities.Modules.PortalModuleBase
  Implements Entities.Modules.IActionable

    Public ReadOnly Property ModuleActions() _
          As Entities.Modules.Actions._
          ModuleActionCollection Implements _
          Entities.Modules.IActionable.ModuleActions
        Get
            Dim Actions As New Entities.Modules_
                  .Actions.ModuleActionCollection
            Actions.Add(GetNextActionID, _
                  Localization.GetString(_
                  Entities.Modules.Actions._
                  ModuleActionType.EditContent, _
                  LocalResourceFile), _
                  Entities.Modules.Actions._
                  ModuleActionType.EditContent, _
                  "", "", EditUrl(), False, _
                  Security.SecurityAccessLevel.Edit,_
                  True, False)
            Return Actions
        End Get
    End Property

    Protected Sub Page_Load(ByVal sender _
              As Object, ByVal e As System.EventArgs)
        Try
            Dim objModules As ModuleController_
                       = New ModuleController
            If Not Page.IsPostBack Then
                If (Not (CType(Settings("showform"), _
                         String)) Is Nothing) Then
                    If (CType(Settings("showform"), _
                              String) = "No") Then
                        ' Do not allow messages to be added
                        FormView1.Visible = False
                        lblAddMessage.Visible = False
                    End If
                End If
            Else
                Me.GridView1.DataBind()
            End If
        Catch ex As Exception
            Exceptions.ProcessModuleLoadException(Me, ex)
        End Try
    End Sub

    Protected Sub NewItem(ByVal sender As Object, _
              ByVal e As System.Web.UI.WebControls._
              FormViewInsertEventArgs) _
              Handles FormView1.ItemInserting
        e.Values.Item("ID") = 0
        e.Values.Item("ModuleId") = ModuleId.ToString()
        e.Values.Item("DateEntered") = _
              DateTime.Now.ToShortDateString
    End Sub

    Protected Sub SetModuleID(ByVal sender As _
              Object, ByVal e As System.Web.UI._
              WebControls.ObjectDataSourceSelectingEventArgs) _
              Handles ObjectDataSource_Tasks.Selecting
    e.InputParameters("ModuleId") = ModuleId.ToString
    End Sub
End Class
End Namespace

Review

  • Data Access Layer (DAL) (Done)
  • Business Logic Layer (BLL) (Done)
  • Presentation Layer (UI) (Done)

Build the Site

From the toolbar, select Build, then "Build Web Site":

Creating_A_DNNModule/image078.jpg

The site should build with no errors:

Creating_A_DNNModule/image079.jpg

From the toolbar, select Debug, then Start Without Debugging:

Creating_A_DNNModule/image021.jpg

The website will come up. Click "Guest Book" on the menu bar:

Creating_A_DNNModule/image080.jpg

The module will now show:

Creating_A_DNNModule/image081.jpg

History

  • 21st January, 2007: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here