Nikolaos Kantzelis ASP.Net Blog

This blog will focus on ASP.NET Framework

Sponsors

About Me

Great Blogs

February 2011 - Posts

How to create selectable themes in your ASP.Net applications

In this post I am going to show you something that we see in most websites. When we visit a website we are given the choice through a control to select the theme(colors,font size,font family) that we want to be applied to the site.

In almost all asp.net web sites we define the look and feel of the site through Themes,skins,Master Pages and Stylesheets.

I assume that you know a little bit about CSS,XHTML. I assume that you have little knowledge of web forms and master pages.

Before you go on it will be useful if you have a look in this other post of mine.

1) Launch Visual Studio 2005/2008/2010. Express editions will work fine.

2) Create an empty asp.net web site. Choose an appropriate name. Choose VB.Net as the development language.

3) Add an item to your website, a master page. Name it Master.master.

4) Add an ASP.Net special folder to your site, "App_Themes". Add two Theme folders under it. Name the first Theme folder, "Gray" and the other one "Orange".

5) Add another item in your site, a stylesheet. Name it "Site.css".Place this .css file under the Gray Theme folder. The code for the site.css follows.

 

* {
  margin0;
  padding0;
}


body {
  font62.5%/1.6 "Lucida Grande", "Lucida Sans", "Lucida Sans Unicode", 
Verdana, sans-serif;
  background-color:#D4D4D4;
  text-aligncenter
  min-width760px;
}

h1 {
  font-size2.4em;
  font-weightnormal;
}

h2 {
  font-size2.0em;
  font-weightnormal;
}

pli {
  font-size1.4em;
}

h1h2p {
  margin1em 0;
}

#header {
  height50px;
  background-color:#b0b0b0;
  padding20px;
}

#header h1 {
  margin0;
  color:#1c93c1;
}


#mainNav {
  margin0;   
  padding0;
  background#2683AE;
  list-style-typenone;
  width180px;
  font-size:1.4em;
  font-family:Verdana;
  floatleft; 
 }
 


#mainNav a {   
  displayblock;  
  color#FFF;
  text-decorationnone;
  padding0 15px;
  line-height2.5;
  border-bottom1px solid #FFF;
}
#mainNav a:hover { 
  background#C1C1C1;
  color:red;
}

#mainNav #con a {
  bordernone;
}

#wrapper {
  width720px
  margin0 auto
  text-alignleft;
  background#fff url('../../Styles/images/bg-fixed.gif') repeat-y left top;
}

#content { 
  width520px
  floatright
}

#footer {
  background-color:#b0b0b0;
  padding1px 20px;
  clearboth
  color:Red;
  font-family:Batang;
}

 

6) Place the site.css file under the Orange Theme folder as well. We will make some changes to the .css file so we give an "orangish" look and feel.Τhe only changes I have made to the original site.css are the following:(in bold are only the changes)

body {
  font62.5%/1.6 "Lucida Grande", "Lucida Sans", "Lucida Sans Unicode",
 Verdana, sans-serif;
  background-color:#3b5998;
  text-aligncenter
  min-width760px;
}
#header {
  height50px;
  background-color:#bdbdbd;
  padding20px;
}

#header h1 {
  margin0;
  color:#e87a1b;
}
 

 

#mainNav {
  margin0;   
  padding0;
  background#e87a1b;
  list-style-typenone;
  width180px;
  font-size:1.4em;
  font-family:Verdana;
  floatleft
 }
 

7) I have created the markup for the master page. It is simple HTML with the  <@Master> directive on top and the ContectPlaceholder controls.We will have a dropdownlist web server control that the user will choose his desired theme.

<%@ Master Language="VB"  CodeFile="Master.master.vb" Inherits="Master" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta name="author" content="Nikolaos Kantzelis" />
<meta name="keywords" content="asp.net,css,jquery,javascript,mvc,LINQ,
Entity Framework" />
<meta name="description" content="ASP.Net is a framework developed By Microsoft 
to create extensible,scalable,eye catching web applications." />
<meta name="robots" content="all" />

<title>ASP.Net Rules</title>

<asp:ContentPlaceHolder id="HeadContent" runat="server">

</asp:ContentPlaceHolder>
</head>

<body>
<form id="form2" runat="server">
<div id="wrapper">
<div id="header">
<h1>ASP.Net RULES!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</h1>
</div> 
<h3>Select your theme</h3>
 <asp:DropDownList ID="DropDownList1"  runat="server" AutoPostBack="true">
   <asp:ListItem Value="Gray">Gray</asp:ListItem>
   <asp:ListItem Value="Orange">Orange</asp:ListItem>
   </asp:DropDownList>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
   </div>
<div id="content"> 

  
<div id="Div1">
<h1>Lorem ipsum dolor</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy 
nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
<h2>Ea commodo consequat</h2>
<p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy 
nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper.</p>
</p>
</div> 



</div>
<ul id="mainNav"> 
<li class="first"><a href="#">Home</a></li> 
<li><a href="#">Company</a></li> 
<li><a href="#">News</a></li> 
<li><a href="#">Products</a></li> 
<li><a href="#">Services</a></li> 
<li><a href="#">Clients</a></li> 
<li id="con"><a href="#">Contact</a></li> 
</ul> 

<div id="footer">
<p>Copyright © 2011 by NKSolutions. All rights Reserved. 
Site developed by  NKSolutions</p>
</div>


</div>
</form>
</body>
</html>

8) Add another item to your site, a web form. Make sure you choose this master page.

In my case the markup for the default.aspx looks like this

<%@ Page Title=""Language="VB" MasterPageFile="~/Master.master" 
AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
    <p>
        <center><em>THIS IS THE HOME PAGE</em></center></p>
</asp:Content>

 

This is the simplest of pages using a master page.Just make sure that the ContentPlaceHolder properties of the Content controls are set to the right values.

Usually we could have the functionality for selecting  a desired theme from the user,(If we choose to implement the user selection per page-which would be wrong) in the Pre_Init event of the Page class.

But now, very wisely, we have the dropdownlist control on the master page.The problem with the master page is that is not actually a page. It does not inherit from the Page class, it inherits from the UserControl class.

Have a look at the MSDN documentation and you will see something like this.

 Public Class MasterPage
          Inherits System.Web.UI.UserControl

     Member of System.Web.UI
Summary:

Acts as a template and merging container for pages that are composed only of System.Web.UI.WebControls.Content controls and their respective child controls.

 ************************************************

It is clear that we do not have a Pre_Init event in this case.Let me show you how we can solve that.

9) Add another item to your site,a class file. Name it PageClass.vb. We will make this class inherit from the Page class.

The code for this class follows:

Imports Microsoft.VisualBasic

Public Class PageClass
    Inherits Page


 Protected Overrides Sub OnPreInit(e As System.EventArgs)
   MyBase.OnPreInit(e)
    If (Not Request.Form Is Nothing And Request.Form.Count > 0) Then
     Me.Theme = Request.Form(Me.Master.FindControl("DropDownList1").UniqueID)
    End If
 End Sub
   
End Class

 

I override the Pre_Init event of the base class and write my own custom code inside the overridable method.

I set the Theme property of the page (Me) by getting from the master page the UniqueID of the dropdownlist control.

10) The Default.aspx.vb must inherit fromt the PageClass class and not the Page class. So we must change that.

The whole code for the Default.aspx.vb  follows.

Partial Class _Default
    Inherits PageClass

End Class

 

11) Run your application.Initially we do not see any style applied to our page. Choose your theme, Gray or Orange and see the markup being styled accordingly.

All of the pages in your site must inherit from the PageClass class.

Drop me an email if you want the source code.

Hope it helps!!!!

Creating a simple RSS reader using ListView,XMLDatasource,DataPager web server controls

In my last ASP.Net seminar someone noticed that we did not talk at all about the XmlDataSource,ListView,DataPager web server controls.

It is rather impossible to investigate/talk about all issues regarding ASP.Net in a seminar but I promised to write a blog post. I thought that I could combine all those three web server controls to create a RSS reader.

1) Launch Visual Studio 2008/2010. Express editions will work fine.

2) Create an empty asp.net web site. Choose an appropriate name. We will not write any code so choose any development language you want.

3) I will read in my RSS reader application all the posts from this blog- http://weblogs.asp.net/dotnetstories.

4) If you go to this url:http://weblogs.asp.net/dotnetstories/rss.xml,  you will be able to subscribe to my Feeds (all the posts) if you have any suitable RSS Reader application.

Open Internet Explorer and type in the address bar , http://weblogs.asp.net/dotnetstories/rss.xml. You will see the RSS feed and its contents. If you go to see View->Source 

you will see the xml document source. Notice that we have some main items, like rss,category,channel,item,pubDate,link,description,title.All of them have parent/child relationships.

5) Drag and drop on the web form, a ListView control. Also drop an XML Datasource control.

6) Let's configure the XML Datasource control.

<asp:XmlDataSource

    ID="RSSxmlSource"

    DataFile="http://weblogs.asp.net/dotnetstories/rss.xml"

    XPath="rss/channel/item"

    runat="server">

</asp:XmlDataSource>

 

7) We set the DataFile attribute to rss feed url. Then I just create simple XPath expression based on the following relationship.If you want to learn more about XPath click here .

<rss>

<channel>

<item>  </item>

</channel>

</rss>

8) Let's configure the ListView control.

 <asp:ListView

        ID="MyRSSBlog"

        DataSourceID="RSSxmlSource"

        ItemPlaceholderID="PlcID"   

        runat="server">

    <LayoutTemplate>

    
        <br /><center><h2 style="border:2px dashed #000;font-family:Verdana;
        color:#1877d6"><i>Blog posts</i></h2></center><br />

        <asp:PlaceHolder ID="PlcID" runat="server"></asp:PlaceHolder>

    </LayoutTemplate>

    <ItemTemplate>

    <h2><asp:HyperLink ID="myLink"

            runat="server" Target="_blank" 

            NavigateUrl='<%# XPath("link") %>'>
        <h3 style="color:#dd1234;text-decoration:none";><%# XPath("title"%>
         </h3></asp:HyperLink>

        </h2>

            <p><i>It was published on <%# XPath("pubDate"%></i></p>

             <p><i>Belongs to the category: <em style="color:#8c0017">
            <%# XPath("category")%></em></i></p>

  <p style="font-size:12px;color:#66803a"><%# XPath("description"%></p>

    </ItemTemplate>

    <ItemSeparatorTemplate>
    
        <hr style="color:Orange"  />
    
    </ItemSeparatorTemplate>

    </asp:ListView>

 8) Let me explain what I do here.

We set the DataSourceID property of the control to the ID of the XmlDataSource control.

Inside the ListView control we have defined various templates. A LayoutTemplate where I define a simple header and I add a PlaceHolder web server control.

I set the ItemPlaceHolderID property to the PlaceHolder ID property.Then I define the ItemTemplate template.

First I define the link and the title of every post by using "evaluation expressions",using the simplest XPath expressions.

 

        <h2><asp:HyperLink ID="myLink"

            runat="server" Target="_blank" 

            NavigateUrl='<%# XPath("link") %>'>
        <h3 style="color:#dd1234;text-decoration:none";><%# XPath("title"%>
        </h3></asp:HyperLink>

        </h2>

 

 

Then inside the ItemTemplate template I get the remaining of the information(published date,category,description) I want from the xml document.

     <p><i>It was published on <%# XPath("pubDate"%></i></p>

     <p><i>Belongs to the category: <em style="color:#8c0017">
     <%# XPath("category")%></em></i></p>

     <p style="font-size:12px;color:#66803a"><%# XPath("description"%></p>

 

9) Finally I have the ItemSeperator template where I just use some simple markup to seperate the items-posts.

<ItemSeparatorTemplate>
    
        <hr style="color:Orange"  />
    
</ItemSeparatorTemplate>

 

10) Run your website and see the posts displayed on your screen.

11) We have many posts appearing in our reader application and we want some sort of pagination. We will add to the web form a DataPager control.We set the PagedControlID property to the ID of the ListView control.

 

  <asp:DataPager ID="DataPager1" runat="server" PagedControlID="MyRSSBlog" 
PageSize="5">
<Fields><asp:NextPreviousPagerField  /></Fields>

        </asp:DataPager>

 12) Run your website and see the posts displayed on your screen.Now you can page through the posts. There are only 5 posts per page.

 

Hope it helps!!!

Extending web server controls by providing client side functionality through Javascript

In this post I will demonstrate how to extend the functionality of the web server controls by adding client side functionality with Javascript.

Let's move on to our example.

1) Launch Visual Studio 2010/2008/2005. (express editions will work fine). Create a new empty website and choose a suitable name for it.

2) Add a new item in your site, a web form. Leave the default name.

3) We need to add some markup.

 

  <form id="form1" runat="server">
    <div>
    <span id="test1">nikos</span>
    <br />
    <br />
    <br />
      <asp:Button ID="mybutton" runat="server" Text="Click" 
onmouseover="ChangeFontSize()" onmouseout="ChangeBold()" />
    </div>
  </form>

 

4) We will add 2 Javascript functions.The first function changes the size of the text inside the span element. The second one will change the size again and make the text inside the span element bold.This is the javascript code

  <script type="text/javascript">
    
   
    function ChangeFontSize()
    {
        document.getElementById('test1').style.fontSize = '50px'
    }
      
    function ChangeBold()
    {
        document.getElementById('test1').style.fontWeight = 'bold';
        document.getElementById('test1').style.fontSize = '20px'

    }
  </script>

 

5) Run your application and see the text changing size/boldness as you mouse out and over the button.

6) Let's try another way to perform the same operation. We will add the same behaviour programmatically.

Change this line of code

 <asp:Button ID="mybutton" runat="server" Text="Click" 
onmouseover="ChangeFontSize()" onmouseout="ChangeBold()" />
to this one
 <asp:Button ID="mybutton" runat="server" Text="Click"/> 

Leave everything else as it is.

7) In the Page_Load event handling routine type,

mybutton.Attributes.Add("onmouseover""ChangeFontSize()")
mybutton.Attributes.Add("onmouseout""ChangeBold()")
8) Run your application and see the text changing size/boldness as you mouse out and over the button.
9) If you want to execute some Javascript client code when the button is clicked, then you can use the OnClientClick property.
In the Page_Load event handling routine type, 
 mybutton.OnClientClick = "return confirm('Are you sure?')"

10) Run your application and see the text changing size/boldness as you mouse out and over the button. When you click the button then you will see the little javascript confirmation window popping up.
11) Add a new web form to your site.Leave the default name. In this form we want to have a javascript function that adds 2 numbers.
We have 2 textboxes and we enter the values to be added. We have a 3rd textbox that will get the result of the addition. 
We will do that with a javascript function.  In order for this to work we need to pass to the javascript function the ID values of the controls. We can do that using the ClientID property of the textbox controls.
This property gets the ID of the control as it is generated from the ASP.Net in the HTML markup.
12) The markup for the Default2.aspx page is
      <asp:TextBox id="txtnum1" type="text" runat="server"/>

      <asp:TextBox id="txtnum2" type="text" runat="server" />

      <br />
    
      <asp:TextBox ID="txtnum3" runat="server"></asp:TextBox>
     
      <br />
      
    
    <asp:Button ID="BtnAdd" runat="server" Text="Add" 
    OnClientClick=" return Add();" />
 
Notice that we set the OnClientClick attribute of the button web server control to the Javascript function(Add) we will write below.
12) The Javascript code looks like this
   <script language="javascript" type="text/javascript">
    
     function Add()
     {
     var txtnum1 = document.getElementById('<%= txtnum1.ClientID%>');
     var txtnum2 = document.getElementById('<%= txtnum2.ClientID %>');
     var txtnum3 = document.getElementById('<%= txtnum3.ClientID %>');
     var CurrentValue = 0;
    if (txtnum1.value != '' && txtnum2.value != '')
     CurrentValue = parseInt(txtnum1.value) + parseInt(txtnum2.value);
     txtnum3.value = CurrentValue;
     }

</script>
 
12) The Javascript code is very easy.The only thing worth noticing is how we pass dynamically (not hardcoded) the ID of the textbox controls to the Javascript function.
13) Run your application and enter 2 values in the first 2 textboxes. After you click the button a javascript client event will take place.You will see the result of the addition displayed in the 3rd textbox.
Email me if you need the source code.
Hope it helps!!! 
How to access HTML elements from server side code in an asp.net website

In this post I will demonstrate with a hands on example how HTML elements in an .aspx page can be processed exactly like standard ASP.Net server controls.

Basically how to make them accessible from server side code.

1) Launch Visual Studio 2010/2008/2005. (express editions will work fine). Create a new empty website and choose a suitable name for it. Choose VB as the development language.

2) Add a new item in your site, a web form. Leave the default name.

3) Let's say that we want to change the background color of the page, thus access to the body element. We want to do that from our server side code.We must change the markup first

<body id="MyBody" runat="server">

4) In the Page_Load event handling routine of the Default.aspx page, type

 MyBody.Attributes("bgcolor") = "teal"

 Run your site and see the background color of the page changing to teal.

5) If we wanted to have access to the head element, we follow the same path

<head runat="server" id ="theHead">

 In the Page_Load event handling routine of the Default.aspx page, type

  theHead.Title = "This is my first asp.net site"

 Run your site and see the new title.

6) What if we wanted to add a paragraph within our body element?

 In the Page_Load event handling routine of the Default.aspx page, type

  Dim myparagraph As HtmlGenericControl = New HtmlGenericControl("p")

  myparagraph.InnerText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore
  et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
  Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat 
  non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

  MyBody.Controls.Add(myparagraph)

 

 Run your site and see the new paragraph added to our site.

 7) Now we want to add programmatically an asp.net web server control inside a div element. Imagine that we want to add a Hyperlink web server control. Let's first add this div element inside our form element in the Default.aspx page

<div id = "mydiv" runat="server"/>    

In the Page_Load event handling routine of the Default.aspx page, type

        Dim mylink As HyperLink = New HyperLink

        mylink.Text = "DotNetStories Blog"

        mylink.NavigateUrl = "http://weblogs.asp.net/dotnetstories"

        mylink.Target = "_blank"

        mydiv.Controls.Add(mylink)

 

Run your application and see the new control added to our site.

That was a fairly easy post to follow.

Hope it helps!!!

How to profile LINQ to Entities queries in your asp.net applications - part 3

In this post I will continue exploring ways on how to profile database activity when using the Entity Framework as the data access layer in our applications.

If you want to read the first post of the series click here . If you want to read the second post of the series click here.

In this post I will use the excellent (best tool for EF profiling) which is called Entity Framework Profiler. You can download the trial - fully functional edition of this tool from here .

I will use the previous example / sample application. I will create again the simple web site, I use in my second post regarding profiling and EF.

I assume that you have access to a version of SQL Server and Northwind database.

If you do not, you can download and install the free SQL Server Express edition from here. If you need the installation scripts for the sample Northwind database, click here

1) Launch Visual Studio 2010/2008 in Administrator mode. (express editions will work fine). Create a new empty website and choose a suitable name for it. Choose C# as the development language.

2) Add a new item in your site. Add a ADO.Net Entity Data Model and name it Northwind.edmx.Place this file in the App_Code special folder.

3) From the wizard choose (create model from database) and select only the Customers,Orders and Categories tables to be included in our model.

4)  Add a new item to your site, a web form. Leave the default name. Drag and drop a Gridview control on the form.We will get some customers back from our database by applying some filtering.

In the Page_Load event handling routine of the Default.aspx type


          
            using (var ctx = new NorthwindEntities1())
            {
               
                var query = from c in ctx.Customers
                            where c.Orders.Any(o => o.Freight > 500)
                            select c;

                GridView1.DataSource = query;

                GridView1.DataBind();


            }

 

Run your application and see the results.

5)  Add a new item to your site, a web form. Leave the default name-Default2.aspx. Drag and drop a Gridview control on the form.Add a button on the web form.In the Default.aspx page drop a Hyperlink control.

The Hypelink control points to the Default2.aspx page.

<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default2.aspx">
HyperLink</asp:HyperLink>

6) We want to insert a new category in the Categories table.We also want to get the rows in the Category table after inserting a new row.

The code for the Default2.aspx.cs page:


protected void Button1_Click(object sender, EventArgs e)
    {
        InsertIntoCategories();
        LoadCategories();
    }


    void LoadCategories()
    {

       
            using (var ctx = new NorthwindEntities1())
            {
             
                var myquery = from cat in ctx.Categories
                              select cat;

                GridView1.DataSource = myquery;

                GridView1.DataBind();

            }
        }
    

    void InsertIntoCategories()
    {
       
           using (var ctx = new NorthwindEntities1())
            {
               
                Category cat = new Category();

                cat.CategoryID = 10;
                cat.CategoryName = "Nice food";

                ctx.AddToCategories(cat);

                ctx.SaveChanges();

            }


    }

 

7) Run your website and see the records being displayed in the Default.aspx page. Click the hyperlink and you will navigate to the Default2.aspx pag and click the button in that page. Observe the new record added to the Categories table.

8) So far so good. Let's see how to use the external tool to observe the various sql statements executed in the database. 

Inside the folder where you downloaded the Entity Framework Profiler locate the HibernatingRhinos.Profiler.Appender DLL.Add a reference to this DLL from your web site.

9) In the Global.asax file in the Application_Start event type the following.

   void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        HibernatingRhinos.Profiler.Appender.EntityFramework.
EntityFrameworkProfiler.Initialize();
    }

 10) Build your website.Launch the Entity Framework Profiler and make sure it is recording.

Run your website and see the records being displayed in the Default.aspx page. Click the hyperlink and you will navigate to the Default2.aspx pag and click the button in that page. Observe the new record added to the Categories table.

11) In the following steps I will show you a few screenshots of the tool while recording the activity of our website.

 

 

Have a look at the screenshot. There are areas that you can see: the object context, the sort version of the SQL statement, the full version of the sql statement and the application statistics. You can also see the numbers of the rows returned and the duration time. You can also see the alerts if any...

12)  Now let's move on with the demonstration of the tool. When I click on the Analysis tab, I can see the unique queries, the most expensive queries,queries by isolation level, e.t.c. This is a very helpful view because we can have a look at all the queries - and the T-SQL very quickly.

 

13) Let's see the Overall Usage View.


14) Let's have a look at the insert statement.You can see the begin and commit transactions statements.As I have said in another post of mine all the insert,update,delete statements are treated as transactions as far as the Entity Framework is concerned.

 

This is by far the best tool out there for database profiling of applications using EF. We can even see the query plan for every sql statement.

We have options for reporting and filtering. We can save the output of the profiler to a file and load it from it.

We could not demonstrate all the functionality in this post. The options are so many and the only way to find out is to try it for yourself. For more screenshots have a look here .

Hope it helps.

More Posts « Previous page