How to make an ASP.NET user control behave like a custom WebControl – level 200

If you’ve used User Controls for any amount of time, you’ve lamented that there is no containing control for attributes.  With any other custom controls, you have WebControl as the base class, and that allows you to use a <span/> by default or change the TagKey to another tag, and when you declaratively set an attribute like [style=”padding:10px;”], the attribute automatically gets added to the tag.


Not so with User Controls, but they aren’t designed to work that way.  They are meant to be pagelets: a portion of a page.  A User Control can contain anything and doesn’t have to be encapsulated in any control, so there is no tag to add attributes to.


I have made a hybrid User-Custom web control.  It inherits from UserControl, so I have the nice declarative layout, but I needed functionality of a WebControl as well.  I added a WebControl as a member of my user control, and on PreRender, I wrap all my user control contents in this WebControl.  Then I bestow all the attributes of the user control on the WebControl and add the WebControl as the only 1st-level child of the user control.  The end result is that I have a user control that wraps itself in a <span/> or whatever tag I want, and I can set attributes on the Page, and they will get rendered to the browser.  This is especially useful when I need to add a style property or “class”.


Here’s my code-behind.  Feel free to copy/steal my code:



   14     public class Magic : System.Web.UI.UserControl


   15     {


   16         private WebControl _frame;


   17 


   18         public WebControl Frame


   19         {


   20             get {


   21                 this.EnsureChildControls();


   22                 return this._frame;


   23             }


   24         }


   25 


   26         protected override void CreateChildControls()


   27         {


   28             base.CreateChildControls ();


   29 


   30             this._frame = new WebControl(HtmlTextWriterTag.Div);


   31         }


   32 


   33         protected override void OnPreRender(EventArgs e)


   34         {


   35             base.OnPreRender (e);


   36 


   37             Control[] ctrls = new Control[this.Controls.Count];


   38             this.Controls.CopyTo(ctrls, 0);


   39 


   40             foreach(Control ctrl in ctrls)


   41             {


   42                 this.Frame.Controls.Add(ctrl);


   43             }


   44 


   45             foreach(string attribute in this.Attributes.Keys)


   46             {


   47                 this.Frame.Attributes[attribute] = this.Attributes[attribute];


   48             }


   49 


   50             this.Controls.Add(this.Frame);


   51         }


   52 


   53 


   54         private void Page_Load(object sender, System.EventArgs e)


   55         {


   56             // Put user code to initialize the page here


   57         }


   58 


   59         #region Web Form Designer generated code


   60         override protected void OnInit(EventArgs e)


   61         {


   62             //


   63             // CODEGEN: This call is required by the ASP.NET Web Form Designer.


   64             //


   65             InitializeComponent();


   66             base.OnInit(e);


   67         }


   68 


   69         /// <summary>


   70         ///        Required method for Designer support – do not modify


   71         ///        the contents of this method with the code editor.


   72         /// </summary>


   73         private void InitializeComponent()


   74         {


   75             this.Load += new System.EventHandler(this.Page_Load);


   76         }


   77         #endregion


   78     }


Here is my user control markup:



<%@ Control Language=”c#” AutoEventWireup=”false” Codebehind=”Magic.ascx.cs” Inherits=”MagicUserControl.Magic” TargetSchema=”http://schemas.microsoft.com/intellisense/ie5″%>
This is a tag.
<asp:Label Runat=”server”>Yo, buddy</asp:Label>


And here is my Page markup (where my User Control is used):


<uc1:Magic id=”Magic1″ style=”margin: 10px;” myAttrib=”Palermo” Frame-CssClass=”myClass” runat=”server”></uc1:Magic>


See how easy it is now to add any sort of attribute and have it render?  I created this control out of necessity because I wanted the simplicity of user controls with the power and flexibility of a WebControl-derived control.

New Microsoft Certifications (~Dec 2005) – level 000

For a while now, Microsoft has had:



  • Microsoft Certified Systems Engineer (MCSE) – wow, Engineer!

  • Microsoft Certified Solutions Developer (MCSD)

  • and the new Microsoft Certified Application Developer (MCAD)

There are plenty of people with the MCSD that went along with the VB track, and now you pretty much have to use MCSD for .Net to be clear if you have the new certification.  You’ve probably met someone with one of these certifications that was a blabbering idiot, and the cert has lost credibility in your mind. 


I have the MCSD for .Net certification, and I can say from experience that earning the cert was similar to earning a college degree.  As long as you stuck it out, you’d get it.  After all, how many blabbering idiots do you know with a college degree?  If we can’t keep idiots from getting degrees, then how can we possibly expect Microsoft to solve the same problem with their certifications?


Even so, Microsoft is _attempting_ to improve the certification program, and will be introducing some new choices for developers.  For right now, the title is planned to be “Microsoft Certified Professional Developer”.  MCPD.  For us MCSDs, two exams will be required to upgrade the certification.  According to the article at MCP Mag, MCPD requires the person to first earn MCSD.  It seems to me that the new certifications are aimed toward correctly identifying those that can deploy a specific Microsoft technology.


You can do the MCAD now and get certified in either Windows or Web (pick your language), but there is no distinction for those who might be super integration developers:  those writing web services and windows services and class libraries that integrate other systems.  That is just as important, but for now, Microsoft only has the UI tracks. 


Another hole is design.  All the certifications (current and planned) identify those who can use a Microsoft tool or runtime, but they do nothing to ensure that the person understands anything about software design.  Where are the OO questions?  What about other things in software like cyclomatic complexity?  Besides just using .Net to crank out an application, what about the things that differentiate mediocre developers from great ones?  What about security?  These questions go past Microsoft certifications, however, and they apply to every software developer in the industry, not just .Net devs. 


I think industry certifications will come as the software industry matures (but I think back to how many years railroad venders made tracks of different widths).


I expect the certification plans to change a bit before December, but whatever they come out with, I’ll bite:  have to keep that resume current!

Visual Studio Team System presentation at the Austin .Net UG meeting tonight – level 000

Tonight, Chris Menegay will be presenting on Visual Studio Team
System.  As usual, a healthy supper of pizza and soda will be
provided at the Austin Microsoft Technology Center.  Go to
www.adnug.org for more details.  In case you might be new to the
group, I’m one of the officers as well as the South TX INETA
liaison.  More details below:

 Topic:  Implementing Process – Visual Studio 2005 Team System
Overview

Software projects fail for a variety of reasons. Most of the
difficulties are not due to technology, but due to lack of visibility and
predictability. Microsoft’s forthcoming Visual Studio 2005 Team System will
improve on these challenges as well as impact how applications are designed,
developed, tested, and deployed. Visual Studio 2005 Team System will offer
advanced application lifecycle management tools and processes that will assist
organizations in delivering their solutions on time and under budget. In this
session, you will get a glimpse of these new tools and gain an insight into
Microsoft’s approach to this market.

SpeakerChris
Menegay

Software projects fail for a variety of reasons. Most of the
difficulties are not due to technology, but due to lack of visibility and
predictability. Microsoft’s forthcoming Visual Studio 2005 Team System will
improve on these challenges as well as impact how applications are designed,
developed, tested, and deployed. Visual Studio 2005 Team System will offer
advanced application lifecycle management tools and processes that will assist
organizations in delivering their solutions on time and under budget. In this
session, you will get a glimpse of these new tools and gain an insight into
Microsoft’s approach to this market.

Date/Time7/11/2005 5:30:00 PM –
7/11/2005 7:30:00 PM

LocationMicrosoft Technology Center
Stonebridge Plaza,
Building One, 9606 N. Mopac, Ste. 200, Austin, TX
78759
512-795-5300

How to decide: user controls vs. composite controls vs. rendered custom controls

There are several ways to make your own server controls in
ASP.NET.  You may have wondered which type you should make. 
There are two basic types:

  • user controls
  • custom controls

Within custom controls, you have rendered controls, and composite
controls.  A composite control could merely inherit from another
control and change or add something.  More often, though, it
creates many child controls to render inside itself.

A User Control is the easiest to make, and it was originally going to
be called “pagelets” because the creation experience is pretty close to
that of a page.  You have the html view and a code-behind. 
It’s just a snippet of what would go on a page.  You can lay out
your html and add other server controls inside, and then control them
with your code-behind.  This type of control should be considered first.  If you need a control that is specific to a particular application, this type of control is for you.

A custom control is all code and is compiled into an assembly. 
The main benefit is that the assembly can be distributed and shared
among many applications.  If you don’t need to share controls
between applications, then it may be hard to justify using this type of
control.  This control is more time-consuming to create.  One valid reason may be that you need a control all over in
your application.

Within the custom control umbrella, you have the rendered controls and
composite or inherited controls.  I prefer the inherited controls
myself.  Often, I’ll inherit from a Panel (a <div/>) and add
other controls as children.  Another method some prefer is
rendered controls.  This is when you inherit from Control and
override the Render method and output all html yourself.  This can
quickly become cumbersome and if very error-prone.  I would
consider this a last resort.  In some cases, a performance
argument is made, and your decision will have to be based on the
application environment.

In summary, if you need to distrubute controls in an assembly, you will
have to use custom controls and decide between rendered or
composite.  If all your controls will stay with the application,
user controls are the most compelling answer.

A must read for every ASP.NET developer is Developing ASP.NET Server Controls and Components.


In the current events space, contratulations to .Net Junkies for upgrading their blogging engine to Community Server.

Update:  Thank you Fregas for the correction.  I’m very
excited about declaratively setting properties on user controls.

ASP.NET trust levels demystified – level 300

The good news is that most of the web applications I write work just
fine in medium trust, so it’s very easy to run your ASP.NET app in
partial trust.  All it takes is a change to your web.config.
    <system.web>
        <trust level=”Full”/>
       . . ..
    </system.web>

ASP.NET runs at Full trust by default (trust levels didn’t exist in
v1.0).  Change the level attribute above to a different setting to
change the permissions of your ASP.NET code.  You can change your
trust level, and here’s the rundown of what each one means:

  • Full trust – your code can do anything that the account running it can do.
  • High trust – same as above except your code cannot call into unmanaged code. i.e. Win32 APIs, COM interop.
  • Medium trust – same as above except your code cannot see any part of the file system except its application directory.
  • Low trust – same as above except your code cannot make any out-of-process calls. i.e. calls to a database, network, etc.
  • Minimal trust – code is restricted from anything but the most trival processing (calculating algorithms).

The above lines are the most significant differences that would lead
you to choose a particular trust level.  Read more about trust leves and code-access security from MSDN.

Switch Internet Explorer 6.0 to standard-compliant mode – level 200

It’s very easy to have IE render your web pages using current web
standards, but IE operates in “quirks” mode quite a bit, but it depends
on the web author.  If you are using ASP.NET 1.1 with VS 2003,
then this doctype is added for you automatically:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
If you leave this, IE will not render your page using web
standards.  The problem is that the full Url to the DTD is not
included.

To switch IE 6 to standards-mode, change the Doctype to this:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”>

This is the minimum you should do to every page you create with
ASP.NET.  There are other doctypes you should use for other
reasons, but at least change the Doctype to make IE render in
standards-mode.

Here’s a page from Microsoft that explains this more.

Consistent look in multiple browsers: Use a DOCTYPE – level 200

The <!DOCTYPE /> tag in an Html document is very fundamental,
but a good number of people don’t know what it is, and they don’t use
it.  If you are one of them, read on. 

The W3C makes standards recommendations for the web and DOCTYPEs is one of them. 
The Doctype tells the browser what content to expect and what set of
rules to apply.  Look at a web page you created with Visual Studio
2003.  You will notice that it defaults the Doctype to :

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>

If you only test your web applications in Internet Explorer, you
have probably, through trial and error, found the workarounds to make
your web pages look good.  Switch this top line in any page to:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd“>

See what parts of your web page look messed up.  You will
see that CSS is rendered differently in some cases.  There are
plenty of resources on the web for learning the rules of a particular
Html version.  What you want to do is choose a Doctype that will
allow you to write a web page once and have it look good in multiple
browsers.  With that goal in mind, don’t use the Html 4.0
Doctype.  Use at least the Html 4.01 doctype.  There are some
specific CSS rendering *bugs* with the 4.0 Doctype, but you can study
those on your own if you wish.  Here’s a simple web page you can
use to see the difference each Doctype makes (with different browsers
as well). 

<html>
 <head>
  <meta http-equiv=”content-type” content=”text/html;charset=utf-8″ />
  <meta http-equiv=”Content-Style-Type” content=”text/css” />
  
  <style type=”text/css”>
    #myDiv{
     background-color: yellow;
     padding: 5px;
     margin: 5px;
     border-style: double;
     height: 100px;
    }
  </style>
 </head>
 <body style=”margin:0px; background-color:AliceBlue”>
  

Hello, this is a div.

 </body>
</html>

This page is incomplete because it doesn’t have a Doctype at the top.  Choose a doctype from the W3C and
see how this page is rendered.  You won’t see any difference
between Html 4.01 and the Xhtml varieties.  This page doesn’t have
any mal-formed tags, so there’s no observable differences.  Note
that ASP.NET 1.1 server controls don’t render Xhtml, so it may be a
good idea to use the Xhtml 1.0 Transitional Doctype.  ASP.NET 2.0
server controls will render proper Xhtml.

With Internet Explorer, you can control “standards-compliant”
mode.  If your Doctype includes the full Url where the DTD can be
found, it will render with standards in mind.  If the full Url is
left out, it will render in old-style “Quirks mode”  Check out this page by Microsoft that explains how to ensure IE 6 renders in standards mode.

There are valid reasons to choose one Doctype over the other, and
currently I use Html 4.0, Html 4.01 as well as Xhtml 1.0
Transitional.  A gotcha is that VS 2003 puts the Html 4.0 Doctype
at the top of the page without the Url to the DTD.  Excluding the
DTD Url leaves IE in quirks mode, and will render pages differently
that other standards-compliant browsers.  To tell IE to use web
standards, add the DTD Url to the Doctype, and IE will switch its
rendering mode.

I would also recommend reading up on web standards. 
Doing that will take the mystery out of afternoons when you can’t
figure out why your pages don’t render as you expect them too.  If
you know the rules that are being applied, you can create your web
pages faster.

Fix the network settings for the VSTS Beta 2 VPC image – level 100

At Tech Ed, Microsoft handed out DVDs with a VPC image ready to go with:

  • Windows Server 2003 Standard
  • VS Team Suite (included all of Team System and Whidbey).
  • Sql Server 2005 April CTP
  • Microsoft Office 2003
  • Visual Studio Tools for Office.
  • All of it expires in Sept 2006.

This is the one of the best ideas that Microsoft has had!  Many
were feeling the pain of beta installs, especially with Team System, so
now they release VPC images  that are ready to be evaluated. 
I’m loving it.  I’m using this image for all my .Net 2.0 Beta 2
goodness, and I didn’t have to spend hours setting it up.  Hop
over to Microsoft or talk to your local Developer Evangelist (or User
Group) to get your copy of the DVD.

I was frustrated, however, that my image couldn’t get on the
Internet.  After some investigating, I discovered that the network
connection had an explicit IP and a gateway of 198.168.1.1.  I’ve
made that typo before (198 instead of 192), but I just cleared it out,
use DHCP, and now my image can get to the Internet.  A small
oversite on the image-creators, but an easy fix.  I love VPC for
beta software!  I’m diving into all the ASP.NET security
features. 

A _great_ idea with 2.0 is a machine-wide web.config file located at:
%WinDir%Microsoft.NETFrameworkv1.1.4322CONFIG.  If you have a
team of developers that are in charge of an app, you can set the
machine to High trust instead of Full, turn override off, and they
won’t be able to set their app to Full trust (this assumes that you
don’t want them running arbitrary Win32 API calls from their web pages,
or COM interop).