Knowledge is power. We love to share it.

News related to Mono products, services and latest developments in our community.

khorvat

Building a custom ASP.NET project based on MonoX

05/24/2011Categories: MonoX
So you've downloaded MonoX, played with it a bit, changed a few images and portions of CSS, even changed the layout on some pages and set a bunch of Web part properties. Now you want to take it one step further and use it as a foundation for your custom projects. Building a custom project from scratch is a simple task that can be done in just a few steps. Typically most of the custom projects consist of building a custom layout, template, adding pages and Web parts. The actual scope and complexity of the target application will define how these custom things are implemented. 

This tutorial is intended for ASP.NET developers. It describes the process of creating a custom MonoX based project from scratch in MonoX 4.0.

Before you start building custom project we advise you to read the following articles and familiarize yourself with the terms and concepts that will be used in this tutorial:


We will divide this tutorial in the following sections:

  • Unzip MonoX package and create a website in IIS
  • Install MonoX CMS 
How to: Install MonoX on Windows Server 2003
How to install MonoX on Windows Server 2008
How to perform MonoX installation
  • Create a folder structure that you will need
  • Change the configuration files
  • Create a Master page layout
  • Create a MonoX theme and template 
  • Create a Page and add Web parts (modules)

Unzipping the MonoX package and creating a website in IIS
Perform this process only if you didn't install MonoX via WebPI

First thing that we need to do is download the latest version of MonoX CMS that can be found on the Url provided above. When we have MonoX downloaded then we should create a website in IIS and install the MonoX as described in the articles mentioned above. 

Creating a folder structure

In this step we will just suggest what we consider to be a good practice. It is totally up to you what folder structure will be used in your projects. Here is our basic folder structure:

MyProjectName
    Code
        BaseClasses
        Classes
        Layers
            BusinessLayer
            Repositories
    LocalResources
    Controls
    MasterPages
    Pages
    Upload
        Documents
        Flash
        Images
        Media
        WebParts
App_Themes
    MyProjectName
App_Templates
    MyProjectName

Here is a small overview of the folders above:

  • Code - Is basically used to store all of your custom classes.
  • BaseClasses - contains all classes that derive from MonoX classes: these include BaseUserControl, BaseAutoRegisterPart, BasePage, BaseMasterPage, ...  (find out more about these classes here).It is a good practice to inherit these classes form MonoX base classes so you can take advantage of this layer later on in the development process.
  • Classes - a place to store all of your utility classes.
  • Layers BLL and Repository - business layer and data access layer classes go here.
  • LocalResources - If your project requires globalization / localization then we practice to store resource files here
  • Controls, MasterPages and Pages - a good place to store all your UserControls, Master page and Page files.
  • Upload - folder used by the MonoX CMS for all built-in upload processes (e.g. HTML Editor document uploads, Multi file uploads etc.) It is a good practice to have this folder here so it will not be deleted during the MonoX upgrade process.

To have your own styling and to benefit from MonoX templating system copy the /App_Themes/Default theme to /App_Themes/MyProjectName and /App_Templates/Default to /App_Templates/MyProjectName. You can now reference MyProjectName (of course, you will want to use more meaningful name in your real projects) as your new theme name in all pages and controls. 

Changing the configuration files

After we have created a project folder structure, we need to change the configuration files. The majority of users will want to use Visual Studio IDE in their everyday work, so we can proceed by copying the /MonoX/Samples/Solution/ProjectName.sln and /MonoX/Samples/Solution/Portal.csproj to the Web site root folder. Rename ProjectName.sln to MyProjectName.sln and open it in Visual Studio. You can subsequently change the configuration settings - MonoX will work with the default settings, but it is good to know their exact purpose. Also note that any file editor (besides Visual Studio) can be used to make these changes.
If you didn't perform the MonoX installation or your database connection string is not properly set for any other reason, find the following code in the web.config and modify it by entering your username, password, database server and instance names,
<add name="LocalSqlServer" connectionString="Data Source=;uid=;pwd=;database=;Connect Timeout=90;" providerName="System.Data.SqlClient"/>

Change the main upload folder configuration
<add key="MonoXUploadPath" value="/Upload" />
 
<add key="MonoXUploadPath" value="/MyProjectName/Upload" />

Change the e-mail "from" address
<add key="MailFromAddress" value="monox@mono-software.com" />
 
<add key="MailFromAddress" value="support@myprojectname.com" />

Change the application title 
<add key="ApplicationTitle" value="MonoX" />
 
<add key="ApplicationTitle" value="MyProjectName" />

Change the smtp network settings used by MonoX to send e-mails. If you notice a long delay when posting a message to the discussion board, adding a friend or sending a message via MonoX messaging page, chances are that your this setting is not configured correctly, and the SMTP connection is timing out.
<network host="mail.yourdomain.com"  />

 
Creating Master page layouts

Our next step is to create a layout that will be used for all pages by creating a set of ASP.NET master pages. MonoX provides you with a basic master page that should be inherited to harness all of the CMS features: /MonoX/MasterPages/MonoX.master. After we have visually inherited the MonoX.master we can build our layout by entering some HTML, ContentPlaceHolders and PortalWebPartZone to our custom master page. Here are a few samples of a custom layout:

<%@ Master
    Language="C#"
    MasterPageFile="/MonoX/MasterPages/MonoX.master"
    AutoEventWireup="true"
    CodeBehind="Default.master.cs"
    Inherits="MyProjectName.Web.MasterPages.Default"
    EnableTheming="true" %>
 
<%@ Register TagPrefix="ctl" TagName="Header" Src="/MyProjectName/Controls/Header.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Navigation" Src="/MyProjectName/Controls/Navigation.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Footer" Src="/MyProjectName/Controls/Footer.ascx" %>
 
<asp:Content ID="cp" ContentPlaceHolderID="cp" runat="Server">
   <asp:ScriptManagerProxy ID="scriptManagerProxy" runat="server"></asp:ScriptManagerProxy>
    <ctl:Header runat="server" ID="ctlHeader" />
    <table width="950" border="0" align="center" cellpadding="0" cellspacing="0">
        <tr>
            <td width="85" align="left" valign="top">
                <ctl:Navigation runat="server" ID="ctlNavigation" />
            </td>
            <td width="40" align="left" valign="top"
              <asp:ContentPlaceHolder ID="cp" runat="server">
              </asp:ContentPlaceHolder>
                 </td>
        </tr>
    </table>
    <ctl:Footer runat="server" ID="ctlFooter" />
</asp:Content>
Sample 1


<%@ Master
    Language="C#"
    MasterPageFile="/MonoX/MasterPages/MonoX.master"
    AutoEventWireup="true"
    CodeBehind="Default.master.cs"
    Inherits="MyProjectName.Web.MasterPages.Default"
    EnableTheming="true" %>
  
<%@ Register TagPrefix="ctl" TagName="Header" Src="/MyProjectName/Controls/Header.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Navigation" Src="/MyProjectName/Controls/Navigation.ascx" %>
<%@ Register TagPrefix="ctl" TagName="Footer" Src="/MyProjectName/Controls/Footer.ascx" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix="portal" %>
<%@ Register Assembly="MonoSoftware.Web" Namespace="MonoSoftware.MonoX.Controls" TagPrefix="mono" %>
 
<asp:Content ID="cp" ContentPlaceHolderID="cp" runat="Server">
   <asp:ScriptManagerProxy ID="scriptManagerProxy" runat="server"></asp:ScriptManagerProxy>
    <ctl:Header runat="server" ID="ctlHeader" />
    <table width="950" border="0" align="center" cellpadding="0" cellspacing="0">
        <tr>
            <td width="85" align="left" valign="top">
                <ctl:Navigation runat="server" ID="ctlNavigation" />
            </td>
            <td width="40" align="left" valign="top">
                 <mono:PortalWebPartZone HeaderText="BlankHeaderZone" ID="blankHeaderWebPartZone"
                   runat="server" Width="100%" ChromeTemplateFile="LeftColumn.htm" ShowChromeForNonAdmins="false">
                            <ZoneTemplate>
                              <asp:ContentPlaceHolder ID="cp" runat="server">
                              </asp:ContentPlaceHolder>
                            </ZoneTemplate>
                 </mono:PortalWebPartZone>
            </td>
        </tr>
    </table>
    <ctl:Footer runat="server" ID="ctlFooter" />
</asp:Content>
Sample 2

Of course, you will need to create your own header, footer and related controls if you need full customization. These are usually simple ASP.NET user controls. MonoX demo header and footer controls can be used if you just want to change the color scheme, layout and other style elements.

You can read more about the ASP.NET master pages here, and don't forget to lookup the PortalWebPartZone in the MonoX API documentation.

Creating MonoX themes and templates

I have already mentioned that we need to copy the /App_Themes/Default theme to /App_Themes/MyProjectName theme and /App_Templates/Default to /App_Templates/MyProjectName, because these folders would be used for theming (skinning) of all pages and controls. There are two approaches that you can take while creating your custom theme:

  • Create a new theme from scratch
  • Modify an existing MonoX demo theme

Create a new theme from scratch

Creating a new theme from scratch is a cleaner but more complex approach, so I'll just sketch a basic workflow for creating a new theme. We will soon publish a dedicated article on this topic.

  • Design the layout and styling in Photoshop or similar tool
  • Export the layout, styling (HTML, CSS) to the above mentioned theme and template folders
  • Follow the existing MonoX CSS classes and HTML structure while styling master pages, pages and Web parts

Modify existing MonoX demo theme

Modifying the existing MonoX demo theme is simple way of restyling the portal theme in a custom project. First thing that you need to do is to embed your custom CSS to support custom master page layouts (header and footer included). Most real-world projects will not need all standard MonoX Web parts, so you can remove all "surplus" CSS classes and images and have a clean and optimized CSS file. Now you can restyle the CSS sections that you need.

/**** Photo Gallery - START ****/
.photos
{  
    font-family: Trebuchet MS, Arial, Helvetica, sans-serif;
    font-size: 13px;
    color: #666;
}
.photos A:link,
.photos A:active,
.photos A:visited
{
    color: #dc613f;
    text-decoration: none
}
.photos A:hover
{
    text-decoration: underline;
}
 
...
 
/**** Photo Gallery - END ****/

As you can see, all functional sections have START and END tags inside the CSS file so you can easily navigate it and change all of its visual aspects.
The physical layout of a Web part is defined in Web part templates. For example, if you want to modify the photo album templates, you will need to change its template in /App_Templates/MyProjectName/SocialNetworkingTemplates/AlbumList.htm. Template files look similar to this:

<td>
    <div class="album-list">
        <# AlbumCover #>   
        <table cellpadding="0" cellspacing="0">
            <tr>
                <td>
                    <!--<# AlbumName #>--><!--<# ViewButton #>-->
                    <span class="album-title"><# AlbumNameViewButton #></span> <div class="author"><a href="<# AuthorUrl #>" title="<# AuthorToolTip #>"><# AuthorText #></a></div>
                </td>
            </tr>
            <tr>
                <td class="photo-count"><# PhotoCount #></td>
            </tr>
            <tr>
                <td class="descr"><# AlbumDescription #></td>
            </tr>       
            <tr>
                <td class="album-links">
                    <div><# Rating #></div>
                    <span><# EditButton #></span>  
                    <span><# DeleteButton #></span>
                </td>
            </tr>
        </table>
    </div>
</td>

Template files contains standard HTML and a set of predefined tags that are replaced with actual content at runtime. MonoX templating system also supports NVelocity template engine syntax.
You can read more about the ASP.NET Themes here, also you can take a look at the Web part templating sample here.

Creating portal pages and adding some Web parts

Now it is time to use our restyled modules inside the layout we have created in previous steps. We will do so by creating a page that inherits from our BasePage class and visually inherits from the custom Master page. Our empty page should look similar to this:

<%@ Page Language="C#"
    AutoEventWireup="true"
    MasterPageFile="/MyProjectName/MasterPages/MyProjectName.Master"
    Theme="MyProjectName"
    Inherits="MyProjectName.Web.Default"
    Title="MyProjectName Home"
    CodeBehind="Default.aspx.cs" %>
 
<%@ MasterType TypeName="MonoSoftware.MonoX.BaseMasterPage" %>
 
<%@ Register TagPrefix="MonoX" TagName="Editor" Src="/MonoX/ModuleGallery/HtmlEditor.ascx" %>
<%@ Register Assembly="MonoX" Namespace="MonoSoftware.MonoX" TagPrefix="portal" %>
 
<asp:Content ContentPlaceHolderID="cp1" runat="server">
 
                          <MonoX:Editor runat="server" ID="editor" Title="">
                            <DefaultContent>                           
                                <div>
                                <ul>
                                    <li>
                                        Line 1
                                    </li>
                                    <hr style="margin-right: 30px;" />
                                    <li >
                                        Line 2
                                    </li>
                                    <hr style="margin-right: 30px;" />
                                </ul>
                                </div>                         
                            </DefaultContent>
                          </MonoX:Editor>
 
</asp:Content>

It may be a good idea to use WebPartZones as containers for Web parts, as every part that is contained in it (in this case it is a MonoX HTML editor) will expose all of its settings via the administrative toolbar and allow administrators to perform interactive personalization. It is not obligatory and it is not used in this simple example, but you will see this approach in action in a majority of demo MonoX pages.
Let's take a look at the code-behind of our Default.aspx page:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MonoSoftware.MonoX.Utilities;
using System.Web.UI.WebControls;
using MonoSoftware.Web;
using MonoSoftware.MonoX;
using MonoSoftware.Web.Controls;
using System.Text;
 
namespace MyProjectName.Web.Pages
{
    public partial class Default : MyProjectName.Web.BasePage
    {
      protected void Page_Load(object sender, EventArgs e)
      {
      }
    }
}

Not much to see here - our code-behind class is empty, but we wanted to show that is it a good practice to inherit from the MyProjectName.Web.BasePage which in turn inherits from the MonoX BasePage.

Here are some useful links related to this topic:
How to add a MonoX page
How to edit MonoX page content

Conclusion

This article contains a few useful techniques to perform customizations and build applications on top of MonoX. Of course, you are always free to choose your own approach, as there are plenty extensions points built into our CMS. Please look at some projects based on MonoX to see what's possible and get a bit of inspiration:

Simple blog engine:
http://www.my-heat-pump.com 

Combination of a blog, localization and CMS features:
http://www.torjanac.com

Group discount engine powering a network of localized sites:
http://www.promozebra.com

Localized eGovernment portal:
http://www.inspektorat.hr 

Network of job boards:
http://www.cpl.ie

Social networking recruitment portal:
http://www.jobsmarket.ie

Medical scheduling application:
http://v2.anesthesiascheduler.com

Bank loan processing application:
http://app.sbaopen.com

... and many more.

The following resources will explain Web part (module) customization in more detail:
Building a custom Web part
How to: Create a custom pager template
How to: Extend MonoX and ASP.NET Profile
Rated 2.43, 7 vote(s). 
Just two typos above:
1) you woll need (will)
2) Deault (Default) [in one of the samples]
khorvat
Thanks we have fixed the typos.
sonap
By sonap
Hello, I have a question.

I am using your default.master as reference and I am constructing a new one for my project. In there, I place a Header.ascx control wich I develop in my controls folder. But... If I try to place the:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Header.ascx.cs" Inherits="MonoSoftware.MonoX.MasterPages.Header" %>
<%@ Import Namespace="MonoSoftware.MonoX.Resources" %> in my Header.ascx file
there is no such default core file: Header.ascx.cs

That means I have to create it from scratch! Is that so? I dont Know .Net and I am working with tutorials and forum advices.
What should I do for such a simple thing?
( I know that I can just place a simple mark-up in the master (<header>....etc...</header>) but I am interested in making it more structured and dynamic..

Thanx!
khorvat
Hi,

you don't need to implement the CodeBehind, so you should be good if you just place the above mark-up in your page or master page.

BTW can you please post technical questions to support forum.

Regards
Just wanted to know, I already have a html5 template, can I use that with monox
GoodChuck
Hi,

I am trying to create a custom layout and followed the suggestions in this article however whenever I try inheriting BasePage (MonoSoftware.MonoX.BasePage) in my web content page (.aspx) I get the following error:

"Error 17 The type 'Ninject.Web.PageBase' is defined in an assembly that is not referenced. You must add a reference to assembly 'Ninject.Web, Version=3.0.0.15, Culture=neutral, PublicKeyToken=c7192dc5380945e7'."

Any suggestion would be appreciated.
khorvat
Hi Saad Omair,

you can use HTML5 templates with MonoX there are few themes on GitHub that you can fork and change.

Regards
khorvat
GoodChuck,

as this is an article for older version of MonoX there are a few missing bits and pieces, so you need to add Ninject to your solution in order to use base MonoX functionality. MonoX v5+ depends on Ninject DI container so you will need to use DI to do the IoC if you want to switch from MonoX built-in functionality to yours.

Regards
1 2