70-564 - Control Extenders + Control Adapters

Filed under: , , , by:

My two previous posts described how to extend a basic behavior of controls without changing them. Ajax control extenders add Ajax/JavaScript behavior to controls and control adapters can provide different rendering for controls without changing them. One of the disadvantages of control extenders is that they can extend only 1 control, so there is 10 controls to extend, 10 extenders must be added to a page. And if we want to add an extender to each control (we want to extend) in the whole ASP.NET application, we would have to go through all pages and add a lot of code. That would be definitely tedious and could take a lot of time if an application has many pages. But that's where control adapters come in handy. We would need to create an adapter for the control being extended and override CreateChildControls method to generate ControlExtender markup and add it to as a child the control. Make sure that if the adapter overrides the Render and RenderChildren method, it calls the RenderChildren method from an override of the Render method. Of course it is not very common to add extenders to every single control type within a Web application (especially because Ajax Control Extenders require Ajax ScriptManager on a page so we would need to make sure that one is present on the page that contains a control to which an extender will be added), but there might be situations that it would be desirable. For developers who are not aware of this solution that would mean a lot of tedious work so most probable that task would either not be accomplished as someone would decide that it wouldn't be worth so much resources (time and money) or would take a lot of time (and money). In situations like that you can really see the difference between a developer for whom developing is a mere means of earning money and a thriving developer for whom it is also a hobby and excitement.

70-564 - Passed

Filed under: , , , , , by:

It was last week when I took the 70-564 exam and I passed with the score 985/1000. It looks like I got 1 question wrong. Nevertheless, I have earned Microsoft Certified Professional ASP.NET 3.5 Developer title.





Here is my experience with the exam:
  • there is 50 (!) questions (70-503 (WCF) exam also has 50 questions but on the other hand 70-505 (Windows Forms 3.5) exam has only 40 questions) and 120 minutes
  • questions are not harder than those for 70-562 exam, so if you can pass that exam, you can pass this one
  • there is very few questions on Ajax - MCTS ASP.NET 3.5 exam (70-562) had about 10 questions on Ajax but this one maybe 3 or 4. Also I think 1 question was exactly the same as I had at 70-562 exam
  • there is a lot of questions on state management, which is in line with the exam objectives (Manage state of controls and Design a state management strategy).
  • main focus of questions is to test the ability to identify appropriate usage, so in oder words 70-562 exam requires a tester to know how to use something  whereas 70-564 exam requires to know when to use something or which one to use in this scenario
  • the most crucial aspect at the exam is to read questions very carefully - most questions will contain a list of requirements that almost all answers will meet but there will, of course, only 1 answer (unless it is multiple choice question) that will meet every single requirement and every single word in all the requirements. 
  • very often requirement(s) will contain a comma separated list ie.types of files or activities so make sure that answers will satisfy all elements from the list(s). 
I hope those guidelines will be helpful for everyone who considers taking the 70-564 exam, even though everyone could come to the same conclusions after studying the exam objectives. Given the fact that the exam doesn't cover anything more than 70-562 exam does, I would encourage everyone to take 70-564 exam if he or she has passed 70-562 exam with a good score. I waited a month to read a little more about designing enterprise applications using ASP.NET with the focus on requirements and proposed solutions that would meet those requirements. There is really no point to wait unless you were not comfortable with the 70-562 exam.
Next exam on path to MCPD Enterprise Application Developer 3.5 is MCTS 70-561 ADO.NET 3.5, which will be the last one before the final 70-565 exam.

70-564 - Control Adapters

Filed under: , , , by:

When reviewing for the 70-564 exam  I did some practice with Control Adapters and more specifically ASP.NET Web Control Adapters and Page Adapters. It reminded me that not many .NET Web developers are aware of their existence, even though control adapters have been available since .NET 2.0. Of course it doesn't mean that every Web application must utilize a control adapter but in certain scenarios they might save a lot of time required to accomplish the same task without using control adapters. Simply, control adapters are controls that inherit from System.Web.UI.Adapters.ControlAdapter base class. Moreover, control adapters for ASP.NET Web Controls inherit from System.Web.UI.WebControls.Adapters.WebControlAdapter base class and ASP.NET page control adapters inherit from System.Web.UI.Adapters.PageAdapter base class. They are all abstract classes so to create a control adapter, one must inherit them. Control adapters adapt or modifies behavior at key points in the life cycle of the control for which a control adapter has been created. At each stage in the life cycle, where a call to a life cycle method is made, the ASP.NET page framework checks to see if there is an associated adapter for the control and calls on the adapter's associated method instead of the control's method. In many cases, the adapter method may simply defer back to the control's method. An exception to this behavior are adapters for state management in that the adaptive behavior is additive to the control's state. Control adapters are most commonly used to provide target-specific processing during a specific stage of the control life cycle or to customize target-specific rendering. WebControlAdapter class have additional several methods that are specific to rendering tags. PageAdapter class is the starting point for rendering a Web page adaptively. Additionally, the PageAdapter class defines properties and methods that enable adaptive rendering in the context of typical page-level tasks, such as caching or managing page-state persistence. So simply control adapters are a way of providing different renderings for controls without actually modifying the controls themselves. Because control adapters are designed to provide alternate renderings for different clients, you specify control adapter mappings in a .browser file, which is where associations between User Agent strings and browser capabilities are defined. Browser files can be added either in the local App_Browsers directory of an ASP.NET Web application or in the machine-wide %SYSTEM%\Microsoft.NET\Framework\v2.0.50727\Config\Browsers directory. Even though control adapters are associated with a specific browser type, they can be added to the Default.browser file and hence be applied to all clients. Below is an example of creating and using a page adapter, but the same rules apply for creating any control adapter.
ViewStatePageAdapter.cs

using System.Web.UI.Adapters;
using System.Web.UI;
public class ViewStatePageAdapter:PageAdapter 
{
public override PageStatePersister GetStatePersister()
{
return new SessionPageStatePersister(this.Page);
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write("Copyright 2009");
writer.RenderEndTag();
}
}
Default.browser
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.Page"
adapterType="ViewStatePageAdapter" />
</controlAdapters>
</browser>
</browsers>
Default.aspx.cs
public partial class _Default : System.Web.UI.Page 
{
protected override void OnPreRenderComplete(EventArgs e)
{
this.ClientScript.RegisterClientScriptBlock(
this.GetType(),
"DisplayViewState",
"<script>window.status=('ViewState: ' + document.forms[0]['__VIEWSTATE'].value.length + ' bytes');</script>");
}
}
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>View State Page Adapter Test</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" DataSourceID="AdvantureWorks" 
AllowPaging="True" AutoGenerateColumns="False" DataKeyNames="EmployeeID" 
PageSize="50" CellPadding="4" ForeColor="#333333" GridLines="None">
<RowStyle BackColor="#EFF3FB" />
<Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" 
InsertVisible="False" ReadOnly="True" SortExpression="EmployeeID" />
<asp:BoundField DataField="NationalIDNumber" HeaderText="NationalIDNumber" 
SortExpression="NationalIDNumber" />
<asp:BoundField DataField="ContactID" HeaderText="ContactID" 
SortExpression="ContactID" />
<asp:BoundField DataField="LoginID" HeaderText="LoginID" 
SortExpression="LoginID" />
<asp:BoundField DataField="ManagerID" HeaderText="ManagerID" 
SortExpression="ManagerID" />
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
<asp:BoundField DataField="BirthDate" HeaderText="BirthDate" 
SortExpression="BirthDate" />
<asp:BoundField DataField="MaritalStatus" HeaderText="MaritalStatus" 
SortExpression="MaritalStatus" />
<asp:BoundField DataField="Gender" HeaderText="Gender" 
SortExpression="Gender" />
<asp:BoundField DataField="HireDate" HeaderText="HireDate" 
SortExpression="HireDate" />
<asp:CheckBoxField DataField="SalariedFlag" HeaderText="SalariedFlag" 
SortExpression="SalariedFlag" />
<asp:BoundField DataField="VacationHours" HeaderText="VacationHours" 
SortExpression="VacationHours" />
<asp:BoundField DataField="SickLeaveHours" HeaderText="SickLeaveHours" 
SortExpression="SickLeaveHours" />
<asp:CheckBoxField DataField="CurrentFlag" HeaderText="CurrentFlag" 
SortExpression="CurrentFlag" />
<asp:BoundField DataField="rowguid" HeaderText="rowguid" 
SortExpression="rowguid" />
<asp:BoundField DataField="ModifiedDate" HeaderText="ModifiedDate" 
SortExpression="ModifiedDate" />
</Columns>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:SqlDataSource ID="AdvantureWorks" runat="server" 
ConnectionString="<%$ ConnectionStrings:AdventureWorks %>" 
SelectCommand="SELECT HumanResources.Employee.* FROM HumanResources.Employee">
</asp:SqlDataSource>
</div>
</form>
</body>
</html>
Here is the complete solution:


This sample Web Site uses a custom page adapter to store View State in a Web Server Session State. Also it adds to a page a div element with "Copyright 2009" text. A page adds in PreRenderComplete method a javascript that displays page ViewState size in client's browser status bar in order to see the difference of ViewState size with and without the ViewStatePageAdapter (to see the information on the view state size in IE7 and IE8 the following option must be enabled "Allow status bar updates via script").

The ViewStatePageAdapter has removed 25kB of View State infromation from a Web page, which means that 25kB less will be transfered to a client. Also the text we added to one control (PageAdapter) will be displayed in all pages. If a custom control or page adapter has been added go GAC and to machine-wide Default.browser file, it could affect all ASP.NET applications without really making any changes to those applications, so for example instead of displaying a regular page content it could display information about "Maintenance Break". The fact that control adapters can provide different rendering without actually modifying the controls themselves has been used to to create a suite of control adapters that change the rendering of several common ASP.NET controls to take better advantage of CSS (CSS-Friendly ASP.NET 2.0 Control Adapters). That made possible to have GridView control render using html div elements with css styles rather than html table. By looking at the huge power of control adapters, it is very obvious that any thriving ASP.NET developer should have a very good understanding of them and should not be afraid to use them only because there are other developers around that don't have any experience in using them, which is what I face from time to time and what I want to change through my posts.

70-564 - Extending controls with control extenders

Filed under: , , , , by:

Before .NET 3.5 to extend a control meant usually to inherit from a base control and add extra functionality or create a custom control that would contain a control to extend with additional items ie. javascript. But .NET 3.5 introduced another way to extend a control, which is through Ajax Control Extender, but I have experienced that still many developers are not aware of that fact and still use either inheritance (in java keyword extends is equivalent of keyword inherits in VB.NET or ":" in C#) or create a custom control where they could take advantage of ExtenderControl class. That class enables you to programmatically add AJAX functionality (or simple javascript) to an ASP.NET server control. Since it's not based on inheritance, there is no limitation of extending only unsealed controls.Also one extender may extend different types of controls (TextBox, Button, MyTextBox, etc.) - before it would require creating custom class for each type of controls being extended. I believe that's why AjaxControlToolkit contains so many control extenders ie. SliderExtender, RoundedCornersExtender or ModalPopupExtender. But even though there always will be a business need (or rather functional requirement) to create a custom control extender ie. FocusExtender that will apply different css style whenever a target control gets focus and reverts it back to the default css style when a target control has lost focus. Plus target control can be any type of control - TextBox, Button, DropDownList, etc.
Control extender is created by creating a new project of type: ASP.NET Ajax Server Control Extender.


Once created, a project contains a class that inherits from ExtenderControl and a javascript file in which client-side behavior is specified that will be added to a target control being extended.
FocusExtender.cs

using System;
using System.Collections.Generic;
using System.Web.UI;
namespace Extenders
{
[TargetControlType(typeof(Control))]
public class FocusExtender : ExtenderControl
{
protected override IEnumerable<ScriptDescriptor>
GetScriptDescriptors(Control targetControl)
{
ScriptBehaviorDescriptor desc = new ScriptBehaviorDescriptor(
"Extenders.FocusBehavior", targetControl.ClientID);
desc.AddProperty("onFocusCssClass", OnFocusCssClass);
desc.AddProperty("defaultCssClass", DefaultCssClass);
yield return desc;
}
 
protected override IEnumerable<ScriptReference>
GetScriptReferences()
{
ScriptReference sRef = new ScriptReference();
sRef.Name = "Extenders.FocusBehavior.js";
sRef.Assembly = this.GetType().Assembly.FullName;
yield return sRef;
}
 
public string OnFocusCssClass
{
get
{
String s = (ViewState["OnFocusCssClass"] as String);
return s ?? "";
}
 
set
{
ViewState["OnFocusCssClass"] = value;
}
}
 
public string DefaultCssClass
{
get
{
String s = (ViewState["DefaultCssClass"] as String);
return s ?? "";
}
 
set
{
ViewState["DefaultCssClass"] = value;
}
}
}
}
FocusBehavior.js
Type.registerNamespace('Extenders');
Extenders.FocusBehavior = function(element)
{
Extenders.FocusBehavior.initializeBase(this, [element]);
this._onFocusCssClass = null;
this._defaultCssClass = null;
this._focusHandler = null;
this._blurHandler = null;
}
Extenders.FocusBehavior.prototype =
{
initialize : function()
{
Extenders.FocusBehavior.callBaseMethod(this, 
'initialize');
var e = this.get_element();
this._focusHandler = Function.createDelegate(
this, this._onFocus);
this._blurHandler = Function.createDelegate(
this, this._onBlur);
$addHandler(e, 'focus', this._focusHandler);
$addHandler(e, 'blur', this._blurHandler);
},
dispose : function()
{
var e = this.get_element();
if (this._focusHandler)
{
$removeHandler(e, 'focus', this._focusHandler);
this._focusHandler = null;
}
if (this._blurHandler)
{
$removeHandler(e, 'blur', this._blurHandler);
this._blurHandler = null;
}
Extenders.FocusBehavior.callBaseMethod(this, 'dispose');
},
_onFocus : function(evt)
{
var e = this.get_element();
if (e != null)
{
e.className = this._onFocusCssClass;
}    
},
_onBlur : function(evt)
{
var e = this.get_element();
if (e != null)
{
e.className = this._defaultCssClass;
}
},
get_defaultCssClass : function()
{
return this._defaultCssClass;
},
set_defaultCssClass : function(value)
{
this._defaultCssClass = value;
this.raisePropertyChanged('defaultCssClass');
},
get_onFocusCssClass : function()
{
return this._onFocusCssClass;
},
set_onFocusCssClass : function(value)
{
this._onFocusCssClass = value;
this.raisePropertyChanged('onFocusCssClass');
}
}
Extenders.FocusBehavior.registerClass('Extenders.FocusBehavior', Sys.UI.Behavior);

Next, Extenders.dll  can be added to any Web Site project and any control can gain new behavior, which will allow to change its color when it got focus.
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="Extenders" Namespace="Extenders" TagPrefix="MI" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<style type="text/css">
.Normal
{
background-color: White;
color:Black;
font-weight:normal;
}
.Highlight
{
background-color: Blue;
color:White;
font-weight:bold;
}
.HighlightButton
{
background-color: Yellow;
color:Red;
font-weight:bold;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
Username:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
Password:
<asp:TextBox ID="TextBox2" runat="server" TextMode="Password"></asp:TextBox>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>Value1</asp:ListItem>
<asp:ListItem>Value2</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Text="Button1" />
<MI:FocusExtender ID="focusExtender1" runat="server" TargetControlID="TextBox1" OnFocusCssClass="Highlight"
DefaultCssClass="Normal" />
<MI:FocusExtender ID="focusExtender2" runat="server" TargetControlID="TextBox2" OnFocusCssClass="Highlight"
DefaultCssClass="Normal" />
<MI:FocusExtender ID="focusExtender3" runat="server" TargetControlID="DropDownList1"
OnFocusCssClass="Highlight" DefaultCssClass="Normal" />
<MI:FocusExtender ID="focusExtender4" runat="server" TargetControlID="Button1" OnFocusCssClass="HighlightButton"
DefaultCssClass="Normal" />
</div>
</form>
</body>
</html>

And here are the screenshots:


This very simple example shows how one control extender can change behavior of many different types of controls or add some custom javascript to the page. Some developers who are not experienced in Ajax client-side library and creating Ajax behaviors might find writing control extenders a little complex but nowadays it's almost impossible to be a thriving professional .NET ASP.NET Web Developer without having a good understanding of Ajax client-side programming as he cannot take a full advantage of .NET 3.5 and Visual Studio 2008. And the problem is that Ajax will be getting more and more popular so the sooner you get familiar with all features of Ajax, the easier it will be to learn new features of its next versions and next versions of .NET and Visual Studio. I hope this will encourage everyone to get familiar with control extenders and use them to add extra functionality to the existing controls when next time you will have to extend a control.

70-564 - Choosing appropriate ASP.NET Data-Bound WebServer Control

Filed under: , , , by:

One of the skills that 70-564 exam measures is the ability to choose appropriate controls based on business requirements. And when I look at the projects or Web applications I worked with, I don't recall any of them that wouldn't use some data-bound controls. Whether it was displaying shopping cart, list of managed assets, dashboard of CRM system, list of registered users in system, history of mortgage loan installment payments or simply search results based on some criteria, they all have been designed using some data-bound controls.Fortunately, the books do pretty good job describing available data-bound controls, but I haven't found yet a book that would present a simple comparison of those controls so instead of going through 50 - 100 pages, you could just simply look at some chart or 1 page and choose appropriate control based on the requirements. I have found that kind of summaries very helpful - I can better see the similarities and differences, which helps me a lot during exams but also at work when I can instantly propose the appropriate solution, which what every thriving developer should be able to do.

  1. Single record data-bound controls

  2. Multi records data-bound controls

There is a few data-bound controls a developer can choose from and as always fully based on the business requirements. I think new control in .NET 3.5 - ListView - has made a big difference in choosing an appropriate data-bound control. The charts summarize the choice criteria, which are layout (table or custom elements with css) and functionality (sorting, inserting, paging). The principal key is to know which control can support out of the box what we want to achieve. Red X means that the feature is not supported at all, green X means that there is a placeholder for the feature but it requires some custom code (ie. DataGrid out of the box shows Pager item and support setting Pager Size but nothing happens when Next Page button is clicked), and green V means the feature is fully supported. For example, repeater doesn't have any concept of grouping but of course it could be achieved with customizing the control, but there is also DataList or ListView control that support grouping without wasting developer's time on something that somebody has already successfully developed and tested. And when it comes to new DataPager control support, only new control ListView supports it. But of course any data-bound control can support it as long as it implements IPageableItemContainer interface, so we could create a custom control that would inherit from Repeater and implement that interface, hence create a very lightweight data-bound control supporting paging. As always any customization should be first supported by good arguments (improved performance, meeting business rules, improved functionality, etc.)  as what we get out of the box should really cover most scenarios of data-driven ASP.NET applications - it's just a matter of knowing what functionality is supported by what control. And with the good cheat sheet it shouldn't be hard to remember it and use it either during the exam or during developing your next ASP.NET application.

70-564 - Visual Studio 2008 Templates

Filed under: , , , , by:

Choosing appropriate project templates is very crucial, yet many times developers will choose a template they are most accustomed to or sometimes they don't simply know that there's already a template that will meet their need. Very rarely do books describe available templates and developers usually too busy to explore that end up using either the wrong kind of template or create one from scratch, where they could save a lot of time by using something that has already been developed and tested and is ready to use out of the box. Personally I know a few .NET Web Developers that still don't really understand the difference between ASP.NET Web Site and ASP.NET Web Application. That's why I thought it would be good to go through at least Web templates as those are the subject of the 70-564 exam.
There are two kinds of Web templates - Web Site and Web Project, which they can be accessed for example from the context menu of the solution.



1. Web Site templates - below is the screenshot containing all Web Site templates



  • ASP.NET Web Site - introduced in Visual Studio 2005; doesn't have a project file; all classes must be placed in App_Code folder; all classes by default don't contain namespaces; classes can be written in different languages as long as they are in separate subfolders within App_Code folder; to deploy everything must be copied to IIS folder; separate assembly can be created per page hence changes in 1 page will result in recompiling only 1 assembly; web references are added to special folder App_WebReferences; structure of the project is based on file system (folders represent physical system folders)
  • ASP.NET Web Service – this template opens ASP.NET Web Site template and adds web service file (*.asmx) and puts code-behind file to App_Code folder
  • Empty Web Site – this template creates blank ASP.NET Web Site project but without Default.aspx page, web.config file and without App_Data folder
  • WCF Service –  this template opens ASP.NET Web Site template and adds WCF service file (*.svc) and puts code-behind file to App_Code folder
  • ASP.NET Reports Web Site –  this template opens ASP.NET Web Site template and adds Default.aspx page with ReportViewer element and opens a wizard to create a new Report Data Source, which allows you to choose views or tables from which to retrieve data to strongly typed DataSet that is put in App_Code folder.Finally a local report (*.rpdl) is created
  • ASP.NET Crystal Reports Web Site –  this template opens ASP.NET Web Site template and adds Default.aspx page with CrystalReportViewer element and opens a wizard to create a new Crystal Report (*.rpt), which is being placed in the root folder
  • Dynamic Data Entities Web Site – new template (requires .NET 3.5 SP1) provides a scaffolding framework that enables you to create a data-driven application within minutes using ASP.NET Web Site template,  EntityDataSource and ADO.NET Entity Framework
  • Dynamic Data Web Site – new template (requires .NET 3.5 SP1) provides a scaffolding framework that enables you to create a data-driven application within minutes using ASP.NET Web Site template, LinqDataSource and LINQ to SQL.
2. Web Project templates - below is the screenshot containing all Web Project templates.


  • ASP.NET Web Application - introduced in Visual Studio 2003;  require project file, which defines project structure in application; contains bin folder with compiled assembly of the project; no special App_Code folder is required; all classes automatically get a namespace when added to the project;  all classes must be in one language; only visual elements and compiled assemblies must be copied to IIS folder; you can add pre-build and post-build steps during compilation; web reference is added to folder Web References
  • ASP.NET Web Service Application – this template opens ASP.NET Web Application template and adds web service file (*.asmx) with code-behind file to the root folder
  • ASP.NET Ajax Server Control – this template creates a new ASP.NET custom server control that inherits from ScriptControl, which inherits from WebControl class (base class for all ASP.NET Web server controls) and implements IScriptControl (interface with methods to define JavaScript resources of the custom control)
  • ASP.NET Ajax Server Control Extender – this template creates a new ASP.NET control extender that inherits from ExtenderControl, which inherits from Control class (class defines the properties, methods, and events that are shared by all ASP.NET server controls) and implements IExtenderControl (interface with methods to define JavaScript resources with the behavior for an extender control). This templates allows to add custom client behavior to the existing controls and extend their functionality. It can extend different types of controls (buttons, textboxes, etc.) at the same time, where normally you would have to create several custom controls that would inherit from the controls you want to extend.
  • ASP.NET Server Control – this template, known in VS2005 as Web Control Library, creates ASP.NET Server control(s) – classes that inherit from WebControl class and can be added to Visual Studio Toolbox
  • WCF Service Application  – this template opens ASP.NET Web Application template and adds WCF service file (*.svc) and with its code-behind file in the root folder.
  • Dynamic Data Entities Web Application – this is new template (requires .NET 3.5 SP1) provides a scaffolding framework that enables you to create a data-driven application within minutes using ASP.NET Web Application template,  EntityDataSource and ADO.NET Entity Framework
  • Dynamic Data Web Application – this is new template (requires .NET 3.5 SP1) provides a scaffolding framework that enables you to create a data-driven application within minutes using ASP.NET Web Application template, LinqDataSource and LINQ to SQL
All templates described above are Visual Studio 2008 default templates but you can also download custom templates or create your own ones. Creating a template is done by simply exporting your current project to the template file followed by the export wizard. In the same way you can create an item template.




I hope you've found this overview of Visual Studio 2008 templates useful and helpful in deciding what type of template to use when you're going to create a new project next time. Maybe you will need to create a data-driven web site and you will consider using Dynamic Data Entities Web Site template rather than creating your project from scratch - or maybe you will decide to create additional templates so next time you can take advantage of something you've already developed so you can write less code and play more golf.

70-564 Exam

Filed under: , , , by:

After having passed 70-562 exam, I had only 2 more exams to take in order to become Microsoft Certified Professional Enterprise Application Developer. However, when I looked at the syllabus of 70-564 exam and read more about that exam, I decided to take 70-564 exam, which is Pro: Designing and Developing ASP.NET Applications Using the Microsoft .NET Framework 3.5. Passing it would complete all requirements to be recognized as Microsoft Certified Professional ASP.NET 3.5 Developer.
I started from readying the exam syllabus and then I compared it with exams 70-547 (MCPD ASP.NET 2.0), 70-562 (MCTS ASP.NET 3.5) and 70-565 (MCPD Enterprise Applications 3.5). And it seems that 70-564 exam is like 70-562 exam, where previous MCPD ASP.NET exam covered a lot more (technical envisioning and planning, stabilizing and releasing, evaluation of database designing, etc.). Now those objectives are covered by 70-565 exam, which makes exam 70-564 almost identical to 70-562.
Second thing I always to do before starting studying to an exam is reading other people's blogs and forums to learn their experience and look for some tips. Here are the links to some of the web sites I found with information on the exam:
http://www.accelerated-ideas.com/examinfo/default.aspx?id=11897
http://www.zoroja.com/blog/2009/10/11/how-to-study-for-the-ms-70-564-exam/
http://stackoverflow.com/questions/751051/how-to-study-for-microsoft-exam-70-564-asp-net-3-5
http://stackoverflow.com/questions/963998/studying-for-the-70-564-exam
http://blog.campbellgunn.com/2009/06/passed-exam-70-564-today/
http://www.ms-faqs.com/content/12/47/en/what-books-should-i-study-to-pass-exam-70_564.html
http://www.jumpadvance.com/resources
http://omgili.com/jmp/
That helped me established the following facts about the exam:
- The content is almost identical to 70-562 so if you can pass 70-562, you can pass 70-564
- The exam is very 3.5 centric, which means that extra time should be spent of things like WCF, Ajax, LINQ, ListView, DataPager, aspnet_merge, etc.
- There is no study book for the exam and the book for the previous exam (70-547) is only a waste of time. Generally, it seems that about four to five books are needed to cover the exam's material - a book for AJAX, LINQ or ADO.NET 3.5 that includes LINQ, ASP.NET custom control, designing including Master pages and a security book.
- You just needed to read the questions very carefully - I'm guessing that there might be more than 1 answer (maybe even all) that would solve the problem but the task is to find the one that meets all requirements or is the most efficient or is the easiest to implement or is simply the best practice.
I especially liked the idea that if you can pass 70-562, you can pass 70-564 exam. That was one of the reasons that I decided to start studying to this exam plus the fact that I have a voucher valid till December, 31st 2009 with 30% off on the exam. And of course the fact that I passed 70-562 a few days ago, so it seems I don't have to learn much for this exam.
The books I'm going to use are as follows:
Professional ASP.NET 3.5
Introducing Ajax
Professional Linq
ASP.NET 2.0 -Advanced Topics
ASP.NET 2.0 - Core Reference
ADO.NET 2.0 - Core Reference
Programming WCF
Learning WCF - Hands-on Guide
ASP.NET 3.5 Enterprise Application Development with Visual Studio 2008: Problem Design Solution
Building a Web 2.0 Portal with ASP.Net 3.5
Professional ASP.NET 2.0 Design: CSS, Themes, and Master Pages
Pro ASP.NET 2.0 E-Commerce in C# 2005
There is a lot of books and some of them contain information on ASP.NET 2.0 but they still contain a lot of very useful information and there is no 3.5 equivalent. And due to the fact that I have already read those books, they will be used mostly as a reference to read through examples with main focus how the proposed solutions have met the original requirements, which should help with choosing the best answer during the exam - but most of all during real life project when a developer is responsible for gathering requirements and proposing the best solution, which is probably one of the most crucial elements during SDLC, that has a huge impact on the overall success of a project. And I guess that's why this exam's syllabus is not to measure more knowledge but to measure skills to follow requirements and to know how to utilize the knowledge you have acquired. And those are the skills that every thriving developer should possess.

Exam 70-562 - Custom controls with custom events

Filed under: , , by:

If you study the books I mentioned in my previous post you will find there how to design custom UserControl, WebControl, CompositeControl, CompositeDataBoundControl. You will learn there how to use some of their methods like EnsureChildren, CreateChildControls, ReCreateChildControls, PerformDataBinding, or EnsureDataBound. But when it comes to adding custom events to your custom control those books mention only 1 way - by declaring public event as a field in your class. And I think there's only a few developers that know the other way, and building custom controls is something that web developer does on a daily basis or at least very often. So what's the secret alternative? It is using System.ComponentModel.EventHandlerList class. And it is interesting that this class has been in .NET since version 1.1 and it's not very common - maybe because there is no examples in MSDN. So what's so interesting about this class? Let's declare 3 custom controls: without any events, with events are public fields and with EventHandlerList:

public class CustomDetailsView1 : WebControl
{
public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
{
base.RenderControl(writer);
}
}
public class CustomDetailsView2 : WebControl
{
public event DetailsViewCommandEventHandler ItemCommand;
public event EventHandler ItemCreated;
public event DetailsViewDeletedEventHandler ItemDeleted;
public event DetailsViewDeletEventHandler ItemDeleting;
public event DetailsViewInsertedEventHandler ItemInserted;
public event DetailsViewInsertEventHandler ItemInserting;
public event DetailsViewUpdatedEventHandler ItemUpdated;
public event DetailsViewUpdateEventHandler ItemUpdating;
public event EventHandler ModeChanged;
public event DetailsViewModeEventHandler ModeChanging;
public event EventHandler PageIndexChanged;
public event DetailsViewPageEventHandler PageIndexChanging;
public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
{
base.RenderControl(writer);
}
}
public class CustomDetailsView3 : WebControl
{
protected EventHandlerList _events;
public event DetailsViewCommandEventHandler ItemCommand
{
add
{
if (_events == null)
_events = new EventHandlerList();
_events.AddHandler("ItemCommand", value);
}
remove
{
if (_events != null)
_events.RemoveHandler("ItemCommand", value);
}
}
public event EventHandler ItemCreated
{
add
{
if (_events == null)
_events = new EventHandlerList();
_events.AddHandler("ItemCreated", value);
}
remove
{
if (_events != null)
_events.RemoveHandler("ItemCreated", value);
}
}
...
...
public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
{
base.RenderControl(writer);
}
}
As you see if a custom control has many events that are very rarely used, a solution with EventHandlerList guarantees that your custom control won't use space unless an EventHandler has been added. I have tested how efficient is the solution with EventHandler vs using events.
Here are my test scenarios:
static void CustomDetailsView1Test()
{
System.GC.Collect();
Console.WriteLine("Memory test of CustomDetailsView control with no custom events");
Console.WriteLine("Before instantiation: "+System.GC.GetTotalMemory(true));
CustomDetailsView1 ctl = new CustomDetailsView1();
System.GC.KeepAlive(ctl);
Console.WriteLine("After instantiation: "+System.GC.GetTotalMemory(true));
ctl.Dispose();
ctl = null;
}
static void CustomDetailsView2Test()
{
System.GC.Collect();
Console.WriteLine("Memory test of CustomDetailsView control with custom events as fields");
Console.WriteLine("Before instantiation: "+System.GC.GetTotalMemory(true));
CustomDetailsView2 ctl = new CustomDetailsView2();
System.GC.KeepAlive(ctl);
Console.WriteLine("After instantiation: "+System.GC.GetTotalMemory(true));
ctl.ItemCreated += new EventHandler(ctl_ItemCreated);
Console.WriteLine("After hooking up to ItemCreated event: "+System.GC.GetTotalMemory(true));
ctl.ItemDeleting += new DetailsViewDeletEventHandler(ctl_ItemDeleting);
Console.WriteLine("After hooking up to ItemDeleting event: "+System.GC.GetTotalMemory(true));
ctl.Dispose();
ctl = null;
}
static void CustomDetailsView3Test()
{
System.GC.Collect();
Console.WriteLine("Memory test of CustomDetailsView control with custom events as elements of EventHandlerList");
Console.WriteLine("Before instantiation: "+System.GC.GetTotalMemory(true));
CustomDetailsView3 ctl = new CustomDetailsView3();
System.GC.KeepAlive(ctl);
Console.WriteLine("After instantiation: "+System.GC.GetTotalMemory(true));
ctl.ItemCreated += new EventHandler(ctl_ItemCreated);
Console.WriteLine("After hooking up totemCreated event: "+System.GC.GetTotalMemory(true));
ctl.ItemDeleting += new DetailsViewDeletEventHandler(ctl_ItemDeleting);
Console.WriteLine("After hooking up to ItemDeleting event: "+System.GC.GetTotalMemory(true));
ctl.Dispose();
ctl = null;
}
In order to find out how much memory is used by each control I use System.GC.GetTotalMemory method True value of method argument to force full collection. This method retrieves total number of bytes allocated, therefore I can check how much memory is used by each control. CustomDetailsView1 control has no events so it gives information how much memory a control needs. CustomDetailsView2 control is the same as CustomDetailsView1 but it contains events as fields so our test case shows how much memory all events require. And last test case shows how much memory is required before hooking up to an event and afterwards so we can tell how efficient is using EventHandlerList when there is no events hooked up and when there are. Here are the results:

The results are somehow interesting. Our custom control without events requires 80 bytes, with all events: 128 bytes and with EventHandlerList without any events hooked up - 84 bytes. Great! But what happens if we hook up to two events. For control with events as fields it required 32 bytes to do that but for control using EventHandlerList it was 96 bytes plus additional 12 bytes to instantiate EventHandlerList object. In my example I used constant strings as keys to add or remove handler from a list but usually the EventHandlerList is used as follows:
public class CustomDetailsView : WebControl
{
protected EventHandlerList listEventDelegates = new EventHandlerList();
static readonly object itemDeletingEventKey = new object();
public event DetailsViewDeleteEventHandler ItemDeleting
{
add { listEventDelegates.AddHandler(itemDeletingEventKey, value); }
remove { listEventDelegates.RemoveHandler(itemDeletingEventKey, value); }
}
public void Delete()
{
if (listEventDelegates[itemDeletingEventKey] != null)
(listEventDelegates[itemDeletingEventKey] as DetailsViewDeleteEventHandler)(this, EventArgs.Empty);
}
}
In this example static read only object (being a key in the list) and EventHandlerList are created (even if no method has been hooked up to the event). This makes the things even worse and makes that EventHandlerList is not a very good solution to save some memory. The only benefit I could see is if there is a special business need to control adding or removing handler to your events, however even though this solution should be only considered as a last resort. Given that this topic is fairly advanced, I would presume that it would be covered more likely by 70-564 exam rather than 70-562, but I couldn't stop sharing it as I couldn't understand why none of my books mention about it. So if developers who study to 70-562 exam don't find it useful, then hopefully will developers who want to be more knowledgable about designing custom events in their custom controls and maybe when they encounter a solution using EventHandlerList, they will understand what are the drawbacks of using it, and they might replace it with event fields and save some memory that busy Web Server needs.