You are on page 1of 23

Creating a DotNetNuke Module - For Absolute Beginners

How to create a DotNetNuke module using VS Express - for DotNetNuke 4.


Introduction
This article explains in detail the process of creating a DotNetNuke module.
Requirements
To use this tutorial, you need: VS Express (here), SQL Server Express (here), DotNetNuke Starter Kit 4.x
(here). Dont attempt to create modules on production installation of DotNetNuke; you will invariably screw up
installation and will have to restore DB or re-install.
Setup
1. Install VS Express (here).
2. Install SQL Server Express (here).
3. Follow directions here to install DotNetNuke Starter Kit and to create a DotNetNuke website.

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

Select File from toolbar, then New File:

On next menu, click once on DotNetNuke Module (under My Templates), select "Visual Basic" from Language
dropdown, type "GuestBook." in Name box, and click Add.
If files DataProvider.vb, GuestBookController.vb, GuestBookInfo.vb, SqlDataProvider.vb in ModuleName
directory are under DesktopModules/App_Code then they are in wrong place. Click on ModuleName folder and
drag it under App_Code directly under main root of website. You have to move DesktopModules/ModuleName
and drag ModuleName folder so its under DesktopModules directly under main root of website. Correct way it
should look:

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

Make changes by right-clicking folder name in Solutions Explorer and selecting Rename from menu. You have
to do this twice. Once for folder under App_Code, and then for folder under DesktopModules.
Now, from toolbar, select Build, then Build Web Site:

The website should build without errors.

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

From toolbar, select Debug, then Start Without Debugging. (see more on debugging in this post)
The website should now come up.

Click Login:

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

Click on HOST menu and select SQL

The form will display.


Switch back to VS and in Solution Explorer. Double-click 01.00.00.SqlDataProvider in
DestopModules/GuestBook so that it shows up in main window.

Click once on page, then from toolbar select EDIT then SELECT ALL

Then EDIT and COPY.

Switch back to DotNetNuke website and paste script you copied into window, click "Run as Script" box and
click EXECUTE.
From HOST menu select "Module Definitions"

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

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

Under the Page Functions menu, click Add:

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:

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


Then, click Add:

If you get "Object reference not set to an instance of an object" error, click "Guest Book" link: (However, if
running DotNetNuke on machine lower than Pentium III with 512KB RAM, DotNetNuke will regularly throw
this error).

The module should now appear:

Guest Book Module


We will walk through construction of Guest Book module in these steps:
 Data Access Layer (DAL) - create tables, SPs, alter code in SqlDataProvider.vb and DataProvider.vb.
 Business Logic Layer (BLL) - alter GuestBookController.vb and GuestBookInfo.vb.
 Presentation Layer (UI) - alter ViewGuestBook.ascx, and other files in "DesktopModules/GuestBook".

Data Access Layer (DAL)


To build DAL, we will: create table, create SPs, alter SqlDataProvider.vb. Put code that calls SPs in
SqlDataProvider.vb, alter DataProvider.vb. Put methods (overridden by SqlDataProvider.vb) in DataProvider.vb.
And that's it! It's actually not a lot of code to add to SqlDataProvider.vb and DataProvider.vb. Creating tables
and SPs is standard database programming that you are probably already used to.
From: "DotNetNuke Module Developers' Guide"
Connect To Database
If you have created DotNetNuke website using SS2005 Express, DB connection should already be set up for
you. If you set it up using SS2000 or SS2005, then you may have to set it up. To set up a connection to SS DB,
from toolbar, select View, then Server Explorer.

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

Fill in connection information, and click OK.

Delete Sample Database Objects


You now need to delete table and SPs that template created so that you can make new ones (that happen to
use same names) that guestbook will use. Connection will now show up in Server Explorer. Click plus next to
connection to expand it. Next, click plus icon next to Tables to expand it. Right click on table
YourCompany_GuestBook and select "Delete" and delete table. At this point, module will no longer work in
DotNetNuke web site. It wont work again until you have completed all steps in this tutorial.
Click plus icon next to Store Procedures to expand it. One at a time, right-click on following SPs 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

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

Paste 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]
Dont select "Run as Script" box, and click Execute. (Note: This is a SQL2005 script. It wont work in SQL 2000.
For SQL 2000, you will have to create table manually as explained in next 2 steps.)
Optionally, create table in table designer in VWD. In Server Explorer, right-click Tables and select Add New
Table:

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

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

Paste following script in 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:

Verify that SPs have been created. Switch back to VS, and select View from the toolbar and Server Explorer:

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

Scroll down list of SPs and verify that these SPs have been created:
 YourCompany_GuestBook_Delete
 YourCompany_GuestBook_GetAll
 YourCompany_GuestBook_Insert
 YourCompany_GuestBook_Update

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

In Solution Explorer, expand GuestBook directory under App_code and double-click SqlDataprovider.vb:
Replace 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
' ------------------------------------------ Constructs new SqlDataProvider instance
Public Sub New()
MyBase.New()
'-------------------------------- Read 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
' ------------------------------------------ Gets and sets the connection string
Public ReadOnly Property ConnectionString() As String
Get Return _connectionString
End Get
End Property
' ------------------------------------------ Gets and sets the Provider path
Public ReadOnly Property ProviderPath() As String
Get Return _providerPath
End Get
End Property
' ------------------------------------------ Gets and sets the Object qualifier
Public ReadOnly Property ObjectQualifier() As String
Get Return _objectQualifier
End Get
End Property
' ------------------------------------------ Gets and sets the database ownere
Public ReadOnly Property DatabaseOwner() As String
Get Return _databaseOwner
End Get
End Property
' --------------------------------------------------
' Gets the fully qualified name of SP
' <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
' --------------------------------------------------
' Gets the value for the field or DbNull if field has "null" value
' <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 DataProvider.vb must indicate methods that SqlDataProvider.vb overrides. When we place
those methods in DataProvider.vb, errors will go away.

Alter DataProvider.vb. In Solution Explorer, in GuestBook directory under App_code, double-click


DataProvider.vb.

Replace 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 SqlDataprovider.vb and notice all error messages are gone. Now would be a good time to save.

BLL will get done fast because its only 2 files: simple class file to hold data, and "controller" file that fills class
file with data as well as handle inserting and deleting data.
BLL
To build BLL, we alter: GuestBookInfo.vb, GuestBookController.vb. And that's it! This is step thats usually
hardest for beginners to understand but is really not that complicated. However, ASP.NET 2.0 does provide a
major reduction of code over ASP.NET 1.1 version.
Alter GuestBookInfo.vb
In VS, select View from toolbar and Solution Explorer:

In Solution Explorer, expand GuestBook directory under App_code, and double-click GuestBookInfo.vb:

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
' ------------------------------------------ Gets and sets the Module Id
Public Property ModuleId() As Integer
Get Return _ModuleId
End Get
Set(ByVal value As Integer)
_ModuleId = value
End Set
End Property
' ------------------------------------------ Gets and sets the Item ID
Public Property ID() As Integer
Get Return _ID
End Get
Set(ByVal value As Integer)
_ID = value
End Set
End Property
' ------------------------------------------ gets and sets the Name
Public Property Name() As String
Get Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
' ------------------------------------------ Gets and sets the Email
Public Property Email() As String
Get Return _Email
End Get
Set(ByVal value As String)
_Email = value
End Set
End Property
' ------------------------------------------ Gets and sets the Message
Public Property Message() As String
Get Return _Message
End Get
Set(ByVal value As String)
_Message = value
End Set
End Property
' ------------------------------------------ Gets and sets the DateEntered
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
Alter GuestBookController.vb
In VS, select View from toolbar and "Solution Explorer". In Solution Explorer, expand GuestBook directory
under App_code, and double-click GuestBookController.vb:

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

Review
What did we just do? GuestBookInfo.vb was created. This is just a simple class file. It will hold data.

GuestBookController.vb was created. This class has 4 methods:


 GuestBook_Insert: Inserts items into DB. You pass GuestBookInfo object to this method. Method
opens object and passes individual parameters (module ID, name, email, message) to
YourCompany_GuestBook_Insert method in DataProvider.vb.
 GuestBook_Delete: Deletes items from DB. You pass GuestBookInfo object to this method. Method
opens object and passes individual parameter (ID) to YourCompany_GuestBook_Delete method in
DataProvider.vb.
 GuestBook_GetAll: Gets a recordset from DB. You pass ModuleId parameter to this method. Method
calls YourCompany_GuestBook_GetAll method in DataProvider.vb and returns GuestBookInfo
object filled with data.
 GuestBook_Update: Updates DB. You pass a GuestBookInfo object to this method. Method opens
object and passes individual parameters (ID, module ID, name, email, message, date entered) to
YourCompany_GuestBook_Update method in DataProvider.vb.
A Lot Of Stuff Was Deleted
A lot of code was deleted of GuestBookController.vb. Some of this were optional interfaces that handle
exporting data and searching. These are interfaces that you will want to read about and implement in modules.
However, they arent required, and they are left out for simplicity. A lot of code was eliminated by using code
exclusive to ASP.NET 2.0 and incompatible with ASP.NET 1.1. ASP.NET 2.0 really saves a lot of work and
requires less code.
Presentation Layer (UI)
From now on, files to be altered reside in ".../DesktopModules/GuestBook" directory. To build UI:
 Alter "localization" (.resx) files.
 Alter "controls" and their "code-behind" files: EditGuestBook.ascx, Settings.ascx, ViewGuestBook.ascx.
And that's it! Module will then be complete.

Alter the Localization Files


Localization creates 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 EditGuestBook.ascx.resx to
open it.

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

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

Change content so it matches picture below. The order does not matter. Save and close the file when done.
Double click on "ViewGuestBook.ascx.resx" to open it.

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

Alter the Controls


Module consists of 3 controls (and code-behind files):
 EditGuestBook.ascx, EditGuestBook.ascx.vb
 Settings.ascx, Settings.ascx.vb
 ViewGuestBook.ascx, ViewGuestBook.ascx.vb

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

Replace code with this code (save and close 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":
Replace code with this code (save and close 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"
OnSelectedIndexChanged="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":

Replace code with this code (save and close 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"/></td>
<td style="width: 100px; height: 23px">
<asp:TextBox ID="EmailTextBox" runat="server" Text='<%# Bind("Email")%>' Width="264px"/></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":

Replace code with this code (save and close 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":

Replace code with this code (save and close 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 code with this code (save and close 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 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

Build The Site


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

The site should build with no errors:

From toolbar, select Debug, then Start Without Debugging:


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

Module will now show:

You might also like