Click here to Skip to main content
15,868,073 members
Articles / Web Development / HTML
Article

Creating a DotNetNuke® Module using LINQ to SQL

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
24 Jan 2008BSD10 min read 104.3K   333   34   30
This tutorial will show you how to create a DotNetNuke module using LINQ to SQL.

Image 1

To use this tutorial you need:

  1. Visual Studio Visual Web Developer Express 2008 (download) or Visual Studio 2008
  2. DotNetNuke (download)
  3. ASP.NET 3.5 (or higher) (download)

This tutorial will show you how to create a DotNetNuke module using LINQ to SQL. This will greatly speed module development.

Also see:

Creating a DotNetNuke Module using LINQ to SQL (Part 2)

SETUP

Follow one of the the options below to install DotNetNuke and to create a DotNetNuke Website:
  • Setting-up the Development Environment (using IIS)
  • Setting-up the Development Environment (without IIS)
  • Setting-up the Development Environment on Windows Vista (using IIS)

    Install Visual Studio Express 2008 if you haven't already done so. (download)

    Use Visual Studio 2008 to open DotNetNuke:

    Image 2

    If using DotNetNuke 4.7 or lower, you will get a message like this:

    Image 3

    Click Yes. This will add the needed changes to the web.config to allow LINQ to SQL to run.

    In Visual Studio, select "Build" then "Build Solution". You must be able to build it without errors before you continue. Warnings are ok.

    Are you Ready to Create the Module?

    You must have a DotNetNuke 4 website up and running to continue. If you do not you can use this link and this link to find help.

    DotNetNuke is constantly changing as it evolves so the best way to get up-to-date help and information is to use the DotNetNuke message board.

    Create the Table

    Image 4

    Log into the website using the Host account.

    Image 5

    Click on the HOST menu and select SQL

    Image 6

    Paste the following script into the box:

    CREATE TABLE ThingsForSale (
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ModuleId] [int] NOT NULL,
    [UserID] [int] NULL,
    [Category] [nvarchar](25),
    [Description] [nvarchar](500),
    [Price] [float] NULL
    ) ON [PRIMARY]
    
    ALTER TABLE ThingsForSale ADD
    CONSTRAINT [PK_ThingsForSale] PRIMARY KEY CLUSTERED
    ([ID]) ON [PRIMARY]     

    Select the "Run as Script" box and click "Execute".

    Set Up The Module

    If you haven't already opened the DotNetNuke site in Visual Studio (or Visual Web Developer Express), select File then Open Web Site.

    Image 7

    Select the root of the DotNetNuke site and click the Open button.

    Image 8

    Right-click on the App_Code folder and select New Folder.

    Image 9

    Name the folder LinqThings4Sale.

    Image 10

    In the Solution Explorer, double-click on the web.config file to open it.

    Image 11

    In the web.config file add the line:

    <add directoryName="LinqThings4Sale" />

    to the <codeSubDirectories> section. This is done to instruct ASP.NET that there will be code created in a language other than VB.NET (which is the language of the main DotNetNuke project).

    Image 12

    Right-click on the App_Code folder and select Refresh Folder.

    Image 13

    The LinqThings4Sale folder icon will now change to indicate that the folder is now recognized as a special folder.

    Image 14

    Create the LINQ to SQL Class

    Right-click on the LinqThings4Sale directory located under the App_Code directory and select Add New Item.

    Image 15

    In the Add New Item window, select the LINQ to SQL Classes template, enter LinqThings4Sale.dbml for the Name and select Visual C# for the Language. Click the Add button.

    Image 16

    Wait a few minutes and the Object Relational Designer will open in the Edit window.

    Image 17

    From the toolbar, select View then Server Explorer.

    Image 18

    In the Server Explorer, right-click on the root node (Data Connections) and select Add Connection.

    Image 19

    Enter the information to connect to the database the DotNetNuke site is running on.

    This will not be the connection that the module will use when it runs (you will set that connection in a later step). This is only a connection to allow you to use the Object Relational Designer.Click the OK button.

    Image 20

    When the connection shows up in the Server Explorer, click the plus icon to expand it's object tree to display the tables.

    Image 21

    Locate the ThingsForSale table.

    Image 22

    Click on it and drag and drop it on the Object Relational Designer panel on the left.

    Image 23

    Click anywhere in the white space on the Object Relational Designer panel so that the LinqThings4SaleDataContext properties show in the Properties window (you can also select it from the drop-down in the properties window).

    In the Connection drop-down select SiteSqlServer (Web.config). This instructs the class to use the connection string of the DotNetNuke site that it is running on.

    Image 24

    The connection properties should resemble the graphic on the right.

    Image 25

    Close the LinqThings4Sale.dbl file. You should see a confirmation screen asking you to save it. Click the Yes button.

    Image 26

    The Data Access layer is now complete.

    Create The Module

    In the Solution Explorer, Right-click on the DesktopModules folder and select New Folder.

    Image 27

    Name the folder LinqThings4Sale.


    Image 28

    Right-click on the LinqThings4Sale folder and select Add New Item.


    Image 29


    From the Add New Item box, select the Web User Control template, enter View.ascx for the Name, select Visual C# for the Language, and check the box next to Place code in separate file.

    Image 30

    When the View.ascx page opens, switch to source view and locate the Inherits line.

    Image 31

    Change it to:

    DotNetNuke.Modules.LinqThings4Sale.View

    Save the file.

    Image 32

    Click the plus icon next to the View.ascx file in the Solution Explorer (under the LinqThings4Sale directory) Double-click on the View.ascx.cs file to open it.

    Image 33


    Replace all the code with the following code:

    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    
    using DotNetNuke;
    using DotNetNuke.Security;
    using LinqThings4Sale;
    
    namespace DotNetNuke.Modules.LinqThings4Sale
    {
    public partial class View : DotNetNuke.Entities.Modules.PortalModuleBase
    {
    protected void Page_Load(object sender, EventArgs e)
    {
    
    }
    }
    }

    Image 34

    Save the file. From the Toolbar, select Build then Build Page. The page should build without errors.

    Image 35

    Switch to the View.ascx file and switch to the Design View. From the Toolbox, in the Data section, select the LinqDataSource control.

    Image 36

    Drag the LinqDataSource control to the design surface of the View.ascx page. Click on the options (right-arrow on the right side of the control) and select Configure Data Source.

    Image 37

    In the Configure Data Source box, select LinqThings4Sale.LinqThings4SaleDataContext in the drop-down and click the Next button.

    Image 38

    The Configure Data Selection screen will show. Leave the default options.

    Image 39

    Click the Where button.

    Image 40

    On the Configure Where Expression screen:

    • Select ModuleId in the Column drop-down
    • Select = = in the Operator drop-down
    • Select None for the Source drop-down

    Click the Add button.

    Image 41

    This instructs the LinqDataSource control to filter the results by ModuleId. Each new instance of the module will have a different ModuleId. We will pass this ModuleId to the LinqDataSource control in the code behind in a later step. Click the OK button.

    Image 42

    Click the Finish button.

    Image 43

    On the options for the LinqDataSource control, check the box next to Enable Delete, Enable Insert, and Enable Update.

    Image 44

    Drag a GiridView control from the Toolbox and place it under the LinqDataSource conrol. On the options for the GridView control, select LinqDataSource1 from the Choose Data Source drop-down.

    Image 45

    The GridView will bind to the data source and create columns for the fields in the table.

    Image 46

    On the options for the GridView control, check the box next to Enable Paging, Enable Sorting, Enable Editing, and Enable Deleting.

    Image 47

    On the options for the GridView control, click the Edit Columns link.

    Image 48

    Select the ID column in the Selected Fields section, and under the BoundField properties section, change Visible to False. Do the same for the ModuleId and UserID fields. Click the OK button.

    Image 49

    The GridView will now resemble the image on the right.

    Image 50

    Drag a FormView control to the design surface and place it a few spaces below the GridView (you will have to place a LinkButton control between them in a later step).

    Image 51

    On the options for the FormView control, select LinqDataSource1 on the Choose Data Source drop-down. Click the Edit Templates link.

    Image 52

    On the options for the FormView control, select InsertItem Template on the Display

    drop-down.

    Image 53

    Switch to source view and replace the InsertItemTemplate section with the following code:

    <InsertItemTemplate>
    Category: <asp:DropDownList ID="DropDownList1" runat="server" 
    DataSource='<%# Eval("Category") %>'
    SelectedValue='<%# Bind("Category") %>' EnableViewState="False">
    <asp:ListItem>Home</asp:ListItem>
    <asp:ListItem>Office</asp:ListItem>
    <asp:ListItem>Electronics</asp:ListItem>
    <asp:ListItem>Misc.</asp:ListItem>
    </asp:DropDownList>
      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 />
    Description:<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>
    </InsertItemTemplate>

    Image 54

    Switch to design view, Select Edit Templates and then select InsertItem Template and the form will resemble the image on the right.

    Image 55

    On the options for the FormView control, click on End Template Editing.

    Image 56

    In the Properties for the FormView, set the DefaultMode to Insert.

    Image 57

    Also, in the Properties for the FormView, set Visible to False.

    Image 58

    In the ToolBox, click on the LinkButton control.

    Image 59

    Drag the control to the design surface and drop it between the GridView and the FormView.

    Image 60

    In the properties for the LinkButton (if you have a hard time selecting the properties, switch to source view and double-click on "<asp:LinkButton"), set the Text to Add My Listing.

    Image 61

    Create the Code Behind

    The View.ascx file should now resemble the image on the right. A few code behind methods are now required to complete the module.

    Image 62

    Code Behind for the LinqDataSource Control

    We want to alter the behavior of the LinqDataSource control so that it only shows the records for this particular instance of the module. In addition, when inserting a record we want to insert the current ModuleId and the current UserID. Right-click on the LinqDataSource control and select Properties. The properties will show up in the Properties window (if it doesn't, switch to source view and click on "<asp:LinqDataSource").

    Image 63

    Click on the yellow "lighting bolt" to switch to the "events" for the control

    Image 64

    On the Inserted row type LinqDataSource1_Inserted and click away (or you can just double-click in the box and the name will be inserted for you).

    Image 65

    A method will be automatically "wired-up".

    Image 66

    Add code so the method reads:

    protected void LinqDataSource1_Inserted(object sender, 
    LinqDataSourceStatusEventArgs e)
    
    {
    this.GridView1.DataBind();
    }        

    (this method instructs the GridView to refresh itself after a record has been inserted) On the Inserting row type LinqDataSource1_Inserting and click away.

    Image 67

    Add code so the method reads:

    protected void LinqDataSource1_Inserting(object sender, LinqDataSourceInsertEventArgs e)
    {
    ThingsForSale ThingsForSale = (ThingsForSale)e.NewObject;
    
    ThingsForSale.UserID = Entities.Users.UserController.GetCurrentUserInfo().UserID;
    ThingsForSale.ModuleId = ModuleId;
    }

    (this method casts "e" which is an instance of the object containing the data about to be inserted, as a ThingsForSale object. It then sets the UserID and the ModuleId. ) On the Selecting row type LinqDataSource1_Selecting and click away.

    Image 68

    Add code so the method reads:

    protected void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {
    e.WhereParameters["ModuleId"] = ModuleId;
    }
    (this method passes the current ModuleId to the LinqDataSource control. You will recall that a where clause was defined to expect a ModuleId to be passed.)

    Code Behind for the Add My Listing link

    Double-click on the Add My Listing link.

    Image 69

    Add code so the method reads:

    protected void LinkButton1_Click(object sender, EventArgs e)
    {
    this.FormView1.Visible = true;
    this.GridView1.DataBind();
    }
    (this method makes the entry form visible. )

    Code Behind for the GridView

    Right-click on the GridView control and select Properties. The properties will show up in the Properties window (if it doesn't, switch to source view and click on "<asp:GridView"). Switch to events and enter GridView1_RowDataBound for the RowDataBound row and click away.

    Image 70

    Add code so the method reads:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if ((e.Row.RowType == DataControlRowType.DataRow))
    {
    ThingsForSale ThingsForSale = ((ThingsForSale)(e.Row.DataItem));
    
    if ((PortalSecurity.IsInRole("Administrators"))
    || (Entities.Users.UserController.GetCurrentUserInfo().UserID == (int)ThingsForSale.UserID))
    {
    e.Row.Cells[0].Enabled = true;
    }
    else
    {
    e.Row.Cells[0].Text = " ";
    }
    }
    }        
    (this method casts "e" which is an instance of the object that contains the data for the current row, as a ThingsForSale object. It then compares the UserID to the UserID of the current user. If the UserID matches the current user or the current user is an administrator it enables the first column on the GridView (this allows a user to edit the row)).

    Add Additional Methods to the Code behind

    Add these two methods to the code behind:
    protected void InsertButton_Click(object sender, EventArgs e)
    {
    this.FormView1.Visible = false;
    LinkButton1.Text = "Update Successful - Add Another Listing";
    this.GridView1.DataBind();
    }
    
    protected void InsertCancelButton_Click(object sender, EventArgs e)
    {
    this.FormView1.Visible = false;
    this.GridView1.DataBind();
    }
    (The events for these two methods was created when the code was pasted in the earlier step) Alter the Page_Load method in the code behind so it reads:
    protected void Page_Load(object sender, EventArgs e)
    {
    
    if ((PortalSecurity.IsInRole("Registered Users") || PortalSecurity.IsInRole("Administrators")))
    {
    LinkButton1.Enabled = true;
    }
    else
    {
    LinkButton1.Text = "You must be logged in to add a Listing";
    LinkButton1.Enabled = false;
    }
    }
    (This code determines if the user is logged in and displays the Add Listing link if they are).

    Save the file. From the Toolbar, select Build then Build Page. The page should build without errors.

    Image 71

    Create The Module Definition

    While logged into your DotNetNuke site as "host", in the web browser, from the menu bar select "Host". Then select "Module Definitions".

    Image 72

    Click the black arrow that is pointing down to make the fly-out menu to appear. On that menu select "Create Module Definition".

    Image 73

    In the Edit Module Definitions menu:

    • Enter "LinqThings4Sale" for MODULE NAME
    • Enter "LinqThings4Sale" for FOLDER TITLE
    • Enter "LinqThings4Sale" for FRIENDLY NAME
    • Enter "LinqThings4Sale" for DESCRIPTION
    • Enter "01.00.00" for VERSION

    Then click UPDATE

    Image 74

    Enter "LinqThings4Sale" for NEW DEFINITION Then click "Add Definition"

    Image 75

    Next, click "Add Control"

    Image 76

    In the Edit Module Control menu:

    • Enter "LinqThings4Sale" for TITLE
    • Use the drop-down to select "DesktopModules/LinqThings4Sale/View.ascx" for SOURCE
    • Use the drop-down to select "View" for TYPE

    Then click UPDATE

    Image 77

    In the upper left hand corner of the website, under the PAGE FUNCTIONS menu click ADD.

    Image 78

    In the PAGE MANAGEMENT menu under PAGE DETAILS:

    • Enter "LinqThings4Sale" for PAGE NAME
    • Enter "LinqThings4Sale" for PAGE TITLE
    • Enter "LinqThings4Sale" for DESCRIPTION
    • Click the VIEW PAGE box next to ALL USERS

    Then click UPDATE

    Image 79

    From the MODULE drop-down select "LinqThings4Sale".

    Image 80

    Then click ADD.

    Image 81

    The module will now appear.

    Image 82

    The tutorial is complete.

    Note: In order to run this module on another DotNetNuke site, you need to install ASP.NET 3.5 on the server and modify the web.config of the DotNetNuke site:

    Change: the <system.codedom> section to:

    <system.codedom>
    <compilers>
    <compiler language="vb;vbs;visualbasic;vbscript" type="Microsoft.VisualBasic.VBCodeProvider, System,
    Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" extension=".vb" warningLevel="4">
    <providerOption name="CompilerVersion" value="v3.5"/>
    <providerOption name="OptionInfer" value="true"/>
    <providerOption name="WarnAsError" value="false"/>
    </compiler>
    <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, 
    Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
    <providerOption name="CompilerVersion" value="v3.5"/>
    <providerOption name="WarnAsError" value="false"/>
    </compiler>
    </compilers>
    </system.codedom>
  • Change: the <assemblies> section to:
    <assemblies>
    <add assembly="Microsoft.VisualBasic, 
    Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
    <add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
    <add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
    <add assembly="System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
    <add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </assemblies> 
  • License

    This article, along with any associated source code and files, is licensed under The BSD License


    Written By
    Software Developer (Senior) http://ADefWebserver.com
    United States United States
    Michael Washington is a Microsoft MVP. He is a ASP.NET and
    C# programmer.
    He is the founder of
    AiHelpWebsite.com,
    LightSwitchHelpWebsite.com, and
    HoloLensHelpWebsite.com.

    He has a son, Zachary and resides in Los Angeles with his wife Valerie.

    He is the Author of:

    Comments and Discussions

     
    GeneralCreating Module Package containing Linq to SQL code that's in the App_Code folder Pin
    WilliamMcMaster16-Jun-11 6:46
    WilliamMcMaster16-Jun-11 6:46 
    GeneralRe: Creating Module Package containing Linq to SQL code that's in the App_Code folder Pin
    defwebserver16-Jun-11 7:09
    defwebserver16-Jun-11 7:09 
    GeneralI wish I had seen this a year ago Pin
    TedClarkJr31-Oct-08 21:38
    TedClarkJr31-Oct-08 21:38 
    GeneralA critical error has occurred :/ Pin
    Darren Ramsay30-Oct-08 7:30
    Darren Ramsay30-Oct-08 7:30 
    I followed your article (thanks!) but I get this error when I pull up the page in the browser:

    A critical error has occurred.
    Operator '==' incompatible with operand types 'Int32' and 'Object'

    Any ideas? Thanks.
    GeneralRe: A critical error has occurred :/ Pin
    defwebserver30-Oct-08 7:48
    defwebserver30-Oct-08 7:48 
    GeneralRe: A critical error has occurred :/ Pin
    Darren Ramsay30-Oct-08 7:51
    Darren Ramsay30-Oct-08 7:51 
    GeneralRe: A critical error has occurred :/ Pin
    Darren Ramsay30-Oct-08 8:11
    Darren Ramsay30-Oct-08 8:11 
    GeneralRe: A critical error has occurred :/ Pin
    defwebserver30-Oct-08 8:47
    defwebserver30-Oct-08 8:47 
    GeneralRe: A critical error has occurred :/ Pin
    Darren Ramsay30-Oct-08 8:51
    Darren Ramsay30-Oct-08 8:51 
    GeneralRe: A critical error has occurred :/ Pin
    defwebserver30-Oct-08 9:05
    defwebserver30-Oct-08 9:05 
    GeneralDotnet commerce - looking for programmer in Sri Lanka Pin
    Amarap12-Sep-08 18:35
    Amarap12-Sep-08 18:35 
    GeneralLINQ Issues Pin
    Bob Zagars3-May-08 12:15
    Bob Zagars3-May-08 12:15 
    GeneralRe: LINQ Issues Pin
    defwebserver3-May-08 12:46
    defwebserver3-May-08 12:46 
    GeneralRe: LINQ Issues Pin
    Bob Zagars3-May-08 13:08
    Bob Zagars3-May-08 13:08 
    GeneralRe: LINQ Issues Pin
    defwebserver3-May-08 13:35
    defwebserver3-May-08 13:35 
    GeneralRe: LINQ Issues Pin
    Bob Zagars3-May-08 13:41
    Bob Zagars3-May-08 13:41 
    GeneralRe: LINQ Issues Pin
    defwebserver3-May-08 14:02
    defwebserver3-May-08 14:02 
    GeneralRe: LINQ Issues Pin
    Bob Zagars3-May-08 14:11
    Bob Zagars3-May-08 14:11 
    GeneralRe: LINQ Issues Pin
    Bob Zagars3-May-08 15:17
    Bob Zagars3-May-08 15:17 
    GeneralRe: LINQ Issues Pin
    Bob Zagars3-May-08 16:43
    Bob Zagars3-May-08 16:43 
    GeneralRe: LINQ Issues Pin
    Bob Zagars3-May-08 13:34
    Bob Zagars3-May-08 13:34 
    GeneralRe: LINQ Issues Pin
    defwebserver3-May-08 14:01
    defwebserver3-May-08 14:01 
    QuestionUpgraded to ASP.NET.35 and... not good at all.... please help Pin
    Alberto Bar-Noy30-Apr-08 1:53
    Alberto Bar-Noy30-Apr-08 1:53 
    GeneralThanks for the article Pin
    Dustin Metzgar15-Apr-08 9:08
    Dustin Metzgar15-Apr-08 9:08 
    GeneralGreat Article Pin
    Louwgi29-Jan-08 0:44
    Louwgi29-Jan-08 0:44 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.