Los Angeles, CA *

Creating a Super-Fast and Super-Easy DotNetNuke Module
For absolute beginners! (For DotNetNuke Version 4.3) - Page 3 (Page 2)

Complete The Code

The steps that remain are:

Remember, A DotNetNuke module resides in 2 directories:
  • The Web User Controls and their associated code behind files reside in the "DesktopModules" directory.
  • All other code resides in the "App_Code" directory.

We have created the DAL+ code in the "App_Code" directory. We will now complete the module by creating the Web User Control in the "DesktopModules" directory.


Create The Directory

Right-click on the "DesktopModules" folder and select "New Folder"

Name the new folder "ThingsForSale"


Create the "View" control

Right-click on the "ThingsForSale" folder you just created and select "Add New Item"



In the "Add New Item" box that opens:
  • Click on "Web User Control" under "Visual Studio Installed Templates".
  • Enter "ViewThingsForSale.ascx" in the "Name" box.
  • Make sure the "Place code in a separate file" box is checked.
  • Click the "Add" button.
The "ViewThingsForSale.ascx" file will be created in the "ThingsForSale" folder under the "DesktopModules" folder.

Clicking the "plus" icon next to the file will display the associated code behind file "ViewThingsForSale.ascx.vb".

Create The Grid View and Form View

Double-click on the "ViewThingsForSale.ascx" file and it will open up in the main editing window. Right now the page will be blank. Click the "Source" button at the bottom of the page to switch to source view.



Replace ALL the code with the following code:  
<%@ Control language="vb" Inherits="YourCompany.Modules.ThingsForSale.ViewThingsForSale" CodeFile="ViewThingsForSale.ascx.vb" AutoEventWireup="false" Explicit="True" %>
@ Register Assembly="DotNetNuke.WebUtility" Namespace="DotNetNuke.UI.Utilities" TagPrefix="cc1" %>
@ Register TagPrefix="dnn" TagName="Audit" Src="~/controls/ModuleAuditControl.ascx" %> <br />

<asp:ObjectDataSource ID="ObjectDataSource_ThingsForSale" runat="server" DataObjectTypeName="YourCompany.Modules.ThingsForSale.ThingsForSaleInfo"
="ThingsForSale_Delete" InsertMethod="ThingsForSale_Insert" OldValuesParameterFormatString="original_{0}"
="Page_Load" SelectMethod="ThingsForSale_SelectAll" TypeName="YourCompany.Modules.ThingsForSale.ThingsForSaleController"
asp:Parameter DefaultValue="00" Name="ModuleId" Type="Int32" />

asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
DataSourceID="ObjectDataSource_ThingsForSale" DataKeyNames="ID,UserID,ModuleId" CellPadding="4" CellSpacing="1" EnableViewState="False">
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" Visible="False" />
<asp:BoundField DataField="ModuleId" HeaderText="ModuleId" SortExpression="ModuleId" Visible="False" />
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" Visible="False" />
<asp:BoundField DataField="Category" HeaderText="Category" SortExpression="Category" />
<asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" DataFormatString="{0:c}" HtmlEncode="False" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
There are no Things 4 Sale

br />
asp:LinkButton ID="Add_My_Listing_LinkButton" runat="server" EnableViewState="False">Add My Listing</asp:LinkButton><br />
br />

asp:FormView ID="FormView1" runat="server" DataKeyNames="ID" DataSourceID="ObjectDataSource_ThingsForSale"
DefaultMode="Insert" BorderColor="DarkGray" BorderStyle="Solid" BorderWidth="1px" CellPadding="4" Visible="False">
&nbsp;<asp:DropDownList ID="DropDownList1" runat="server" DataSource='<%# Eval("Category") %>'
SelectedValue='<%# Bind("Category") %>' EnableViewState="False">
Price: $
<asp:TextBox ID="PriceTextBox" runat="server" Text='<%# Bind("Price") %>' Width="56px" CausesValidation="True" EnableViewState="False"></asp:TextBox><br />
<asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="PriceTextBox"
ErrorMessage="Price must be greater than 0" MaximumValue="99999" MinimumValue="1"></asp:RangeValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="PriceTextBox"
ErrorMessage="A price is required"></asp:RequiredFieldValidator><br />
<br />
<asp:TextBox ID="DescriptionTextBox" runat="server" Text='<%# Bind("Description") %>' MaxLength="499" TextMode="MultiLine" Width="286px" EnableViewState="False"></asp:TextBox><br />
<asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert"
Text="Insert" OnClick="InsertButton_Click"></asp:LinkButton>
<asp:LinkButton ID="InsertCancelButton" runat="server" CausesValidation="False" CommandName="Cancel"
Text="Cancel" OnClick="InsertCancelButton_Click"></asp:LinkButton>
<asp:TextBox ID="ModuleIdTextBox" runat="server" Text='<%# Bind("ModuleId") %>' Width="14px" Visible="False"></asp:TextBox>
<asp:TextBox ID="IDTextBox" runat="server" Text='<%# Bind("ID") %>' Width="13px" Visible="False"></asp:TextBox>
<asp:TextBox ID="UserIDTextBox" runat="server" Text='<%# Bind("UserID") %>'
Width="10px" Visible="False"></asp:TextBox>

Click the "Design" button at the bottom of the design window and the screen will look like the image on the right.

What Did We Just Do?

We placed 4 controls on the page:

  • ObjectDataSource Control
    • This is at the top of the image on the right. It is labeled "ObjectDataSource". This control is bound to the "ThingsForSaleController" class created in the earlier step.
  • GridView Control
    • This control is immediately under the "ObjectDataSource" control. This control is bound to the "ObjectDataSource" control and is configured to Select, Update, and Delete.
  • LinkButton Control
    • This is a simple LinkButton that will display messages and when clickable, will allow the FormView control below it to display.
  • FormView Control
    • This control will allow a user to enter an item into the database. it is also bound to the "ObjectDataSource" control and is configured to Insert.



A little more about the ObjectDataSource Control

Hover the mouse over the "ObjectDataSource" control until the small black arrow appears.


Click on it and the configuration menu will appear. click on "Configure Data Source".
The "ThingsForSaleController" class is configured as the Object Data Source.

Click the "Next >" button.

The next screen shows 4 tabs (Select, Update, Insert, and Delete). clicking on each tab reveals that a different method of the "ThingsForSaleController" class is configured to handle each function.

Click the "Next >" button.

The final screen shows the configuration for the parameter that is passed to the Select method.

Here we indicate "ModuleId" with a default value of "00". This is just a "place holder".

The actual value will be supplied at run-time by code in a later step.

In the properties window of the "ObjectDataSource" control we see that the "DataObjectTypeName" is set to our "ThingsForSaleInfo" class that was created in a previous step.

This is how we indicate that this class will be used to pass data between the "ObjectDataSource" control and the "ThingsForSaleController" class.




Create the code behind

Double-click on the "ViewThingsForSale.ascx.vb" file so that it opens up in the design window.



Replace ALL the code with the following code:  
Imports DotNetNuke

Namespace YourCompany.Modules.ThingsForSale

Partial Class ViewThingsForSale

Inherits Entities.Modules.PortalModuleBase

Dim ThingsForSaleInfo_data As New ThingsForSaleInfo

Protected Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

If IsInRole("Registered Users") Or IsInRole("Administrators") Then
Add_My_Listing_LinkButton.Enabled =

Add_My_Listing_LinkButton.Text =
"You must be logged in to add a Listing"
Add_My_Listing_LinkButton.Enabled =

End Sub

Protected Sub SetModuleId(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceSelectingEventArgs) Handles ObjectDataSource_ThingsForSale.Selecting

e.InputParameters("ModuleId") = ModuleId.ToString

End Sub

Protected Sub InsertingItem(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewInsertEventArgs) Handles FormView1.ItemInserting

e.Values.Item("UserID") = Entities.Users.UserController.GetCurrentUserInfo.UserID
"ModuleId") = ModuleId.ToString()
"ID") = 0

End Sub

Protected Sub InsertCancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)

Me.FormView1.Visible = False

End Sub

Protected Sub Add_My_Listing_LinkButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Add_My_Listing_LinkButton.Click

Me.FormView1.Visible = True

End Sub

Protected Sub InsertButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)

Me.FormView1.Visible = False
Add_My_Listing_LinkButton.Text =
"Update Successful - Add Another Listing"

End Sub

Protected Sub HideEditButtons(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound

If e.Row.RowType = DataControlRowType.DataRow Then
ThingsForSaleInfo_data =
CType(e.Row.DataItem, ThingsForSaleInfo)
If IsInRole("Administrators") Or (Entities.Users.UserController.GetCurrentUserInfo.UserID = CInt(ThingsForSaleInfo_data.UserID)) Then
e.Row.Cells.Item(0).Enabled =

e.Row.Cells.Item(0).Text =
End If

End Sub

End Class

End Namespace


What Did We Just Do?


We entered code that will handle:

  • Only allowing a person who is a registered user or an administrator to add an entry (IsInRole("Registered Users") Or IsInRole("Administrators") )

  • Only allowing a person to edit their own entries (Entities.Users.UserController.GetCurrentUserInfo.UserID = CInt(ThingsForSaleInfo_data.UserID)

  • Injecting the current "ModuleId" into the "ObjectDataSource" control.

Hopefully this will help those using Object Data Sources with DotNetNuke. There is a problem of grabbing the current “ModuleId”.

This is a very important value that is exposed by the DotNetNuke core code. This value tells you which instance of the module you are working with. This is important because a person can place multiple instances of your module on a single page. You can’t have them click a button on one instance of the module and return data from another instance of the module.

You can see the solution in “ViewThingsForSale.ascx” and “ViewThingsForSale.ascx.vb”. In the “ViewThingsForSale.ascx” file, in the "ObjectDataSource" control, we indicate the “ModuleId” parameter as a “Select” parameter that will be passed to the “Select” method:
In “ViewThingsForSale.ascx.vb” we have this: 

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

This event fires when the “Select” event is called in the "ObjectDataSource" control, but before the control passes the value to the “SelectAll” method in the "ThingsForSaleController" class. This allows you to pass the “ModuleId” to the "ThingsForSaleController" class (and on to the "ThingsForSale_SelectAll" stored procedure so it returns the proper data).  

Compile and Build The Module

From the toolbar select "Build" then "Build Solution"

The site should build with no errors
In the SOLUTION EXPLORER right-click on the "Default.aspx" page and select SET AS START PAGE.
From the toolbar select DEBUG then START WITHOUT DEBUGGING
The website should now come up.

If you have problems, download the code from here, and compare it to your code.

Remember the module will not work yet because the table and stored procedures have not been created yet. However, the code should still compile at this point.



Next: Complete The Module


DotNetNuke MarketPlace

(C) by Michael Washington - -

DotNetNuke is a registered trademark of Perpetual Motion Interactive Systems Inc.