Jul2008
1

NunoGomesControlToolkit - Improving Web Apps performance

by nmgomes

A few weeks ago I told you about a control toolkit I was making.

I decided to call him NunoGomesControlToolkit and is intended to improve web apps performance by decreasing total page size. This page size reduction is achieved by decreasing control ClientID size.

This control toolkit can be applied to any existing ASP.NET 2.0 Web Aplication by using the tagmapping configuration facility.

To obtain maximum redution it's also recommended to extend webforms, masterpages and usercontrols not from regular Page, MasterPage and UserControl controls from ASP.NET framework but instead use the corresponding control from NunoGomesControlToolkit.

TagMapping is only used for markup interpretation and therefore all dynamic created controls are not mapped. To override this limitation its also included in this toolkit the DynamicControlBuilder class. Use this class to allow tagmapping over dynamic created controls.

As I promise, the control toolkit is now available at code.msdn.microsoft.com.

I'm currently applying the NunoGomesControlToolkit to the BlogEngine.NET 1.3 version, and as soon as I test it I will make it available.

kick it on DotNetKicks.com

Filed in: ASP.NET

Jun2008
18

ASP.NET Controls - Improving automatic ID generation : The ShortIDs Naming Provider (Part 4)

by nmgomes

In the previous posts on this subject I wrote about why automatic ID generation should be improved and how we can improve it. Now I will step forward and show you my own implementation of a specific naming provider.

As we saw in part 3, to create a specific Naming provider you only need to develop your own implementation of SetControlID method.

I named my naming provider ShortIDsProvider and it will have only one specification to meet:

  • it will create IDs in the form Txxx

where T denotes the 'T' character and xxx denotes an unique incremental integer value.More...

Filed in: ASP.NET

Jun2008
2

ASP.NET Controls - Improving automatic ID generation : Architectural Changes ( Part 3)

by nmgomes

Naming container controls are a subclass of standard controls, that differ in the ability to manage child controls' ID, in fact, these naming container controls are the key to unique ID generation. To become a namingcontainer a regular control must implement the INamingContainer interface.

In order to override ASP.NET ID generation we will have to work in two fronts:

  • override regular controls' behavior to decouple the Control.UniqueID property from the Control.ID property
  • override naming container controls to allow us to control how ID generation is done and how to find a control 

More...

Filed in: ASP.NET

May2008
26

ASP.NET - Dynamic Control Mapping

by nmgomes

I already posted here about Tag Mapping and how helpful it can be, but naturally there's are a few improvements that I would like to see available in future framework release.

The one I expect the most is about the capability of mapping dynamic created controls using the same rules as Tag Mapping uses when interpreting the page markup.

Without this capability we can never use widely the tag mapping because whenever we need to create dynamic controls they will be strongly coupled to a specific control implementation.

Imagine this scenario:

  1. First you have built an web application that use standard ASP.NET TextBox  control, some of them dynamically created.
  2. Now, imagine that you want to reuse that application, as is, but instead of ASP.NET Textbox control you want to use your own Textbox implementation.

This task could be easily accomplished using Tag Mapping if no dynamic controls were used, but in this scenario ASP.NET give us no solution, so the application cannot be reused without modifications.

Naturally, you can copy/paste your application and make the necessary changes, or even add a few if statements, but that will only increase complexity and maintenance effort.

Until the .NET team provide us such capability we must do the magic ourselves.

My proposal is an help class (DynamicControlBuilder) that provide us two methods: GetMappedType and CreateControl.

/// <summary>
/// Gets the mapped <see cref="System.Web.UI.Control"/> type.
/// </summary>
/// <param name="type">The <see cref="System.Web.UI.Control"/> type to be mapped</param>
/// <param name="prefix">The namespace prefix.</param>
/// <returns>A <see cref="System.Type"/> object.</returns>
public static Type GetMappedType(Type type, string prefix)
{
    if (!typeof(Control).IsAssignableFrom(type))
    {
        throw new ArgumentOutOfRangeException("type", "Must inherit from Control.");
    }
    Type mappedtype;
    if (!string.IsNullOrEmpty(prefix))
    {
        TagPrefixInfo prefixinfo;
        if (!m_prefixes.TryGetValue(prefix, out prefixinfo))
        {
            throw new ArgumentException("prefix", "No prefix found.");
        }
        else
        {
            type = BuildManager.GetType(string.Format("{0}.{1}, {2}", prefixinfo.Namespace, type.UnderlyingSystemType.Name, prefixinfo.Assembly), false);
            if (type == null)
            {
                throw new ArgumentException("type", "Control not found within specified prefix.");
            }
        }
    }
    if (m_tagMappings.TryGetValue(type.UnderlyingSystemType, out mappedtype))
    {
        return mappedtype;
    }
    return type;
}

/// <summary>
/// Creates a dynamic mapped <see cref="System.Web.UI.Control"/>.
/// </summary>
/// <param name="type">The <see cref="System.Web.UI.Control"/> type to be mapped</param>
/// <param name="prefix">The namespace prefix.</param>
/// <returns>A <paramref name="T"/> object.</returns>
public static Control CreateControl(Type type, string prefix)
{
    Type mappedType = GetMappedType(type, prefix); ;
    return (Control)Activator.CreateInstance(mappedType);
}

The main goal is to enable any of the following usages:

this.Page.Controls.Add(DynamicControlBuilder.CreateControl<System.Web.UI.WebControls.TextBox>("foo"));

this.Page.Controls.Add(DynamicControlBuilder.CreateControl(typeof(System.Web.UI.WebControls.TextBox), "foo"));

this.Page.Controls.Add(DynamicControlBuilder.CreateControl(typeof(System.Web.UI.WebControls.TextBox)));

Try it !

DynamicControlBuilder.cs (7.13 kb)

kick it on DotNetKicks.com

Filed in: .NET | ASP.NET

Feb2008
10

ASP.NET ListView Control

by nmgomes

Some time ago I needed to render hierarchical data to a <ul>/<li> elements structure and also be able to render a special attribute to the <li> Html elements.

Using TreeView control I found no better way than re-implement the Render method, loosing the out-of-the-box binding process.

Since I want to have a control similar to TreeView with all its binding richness I decide to write a ListView control.

This is the typical declaration I want to achieve:

<NG:ListView ID="orderedlistView1" runat="server" DataSourceID="SiteMapDataSource1" Mode="Ordered">
<DataBindings>
<NG:ListNodeBinding DataMember="SiteMapNode" AttributeField="Url" TextField="Title" />
<NG:ListNodeBinding DataMember="SiteMapNode" AttributeField="Url" TextField="Url" Depth="1"/>
<NG:ListNodeBinding DataMember="SiteMapNode" AttributeField="Title" TextField="Title" Depth="2"/>
</DataBindings>
</NG:ListView>

It looks pretty familiar...

In ListView control you can set the Mode property to choose whether to render an ordered list (<ol>) or an unordered list (<ul>).

Using the ListNodeBinding you can also use the AttributeField property to specify aditional attributes to rendered in the <li> html element (ex: <li Url="my Url" >some text</li>).

Also, there's no hierarchy depth limit.

ListView Sample.zip (12.58 kb)


kick it on DotNetKicks.com

Filed in: ASP.NET

Jan2008
30

ASP.NET Controls - Improving automatic ID generation : Concept ( Part 2)

by nmgomes

Before proceeding to the implementation details, let's discuss a little about how ASP.NET handles automatic Id generation.

First of all, the Control.UniqueID property is the key to all major ASP.NET benefits. In fact, ASP.NET gives us unique Id's for each control which give us a deterministic way of recreating page controls. Without this, Viewstate and Events were impossible to achieve.

ASP.NET also gives us the concept of naming controls, that enable us to easily find the correct control and to write more perceptible code, but More...

Filed in: .NET | ASP.NET

Jan2008
23

ASP.NET Controls - Improving automatic ID generation : Introduction ( Part 1)

by nmgomes

Some time ago, while developing a large corporate ASP.NET application with high complex layout requirements and thus, many custom composite controls, I was faced with the following problem:

The generated HTML of my pages don’t meet my bandwidth constrain of 50Kb/page, even after applying the traditional ways to reduce page size (compression, viewstate optimization). Looking carefully at the HTML source I found that a big amount of size has due to the large values 'id' and 'name' attributes. The sum of all this values could be up to 40% of page size, and this became a real issue to me.

So, ASP.NET gives us out of the box a unique strategy to generate the control's ID values. Although such strategy is most of time a satisfactory approach, there are cases when it can become problematic. More...

Filed in: ASP.NET

Jan2008
14

ASP.NET - Tag Mapping

by nmgomes

Tag Mapping is not a new ASP.NET 2.0 feature, but only recently many people discover it.

<system.web>
  <pages>
    <tagMapping>
      <add tagType="System.Web.UI.WebControls.TextBox"
           mappedTagType="MyTextBox"/>
    </tagMapping>
</pages>

The use of Tag Mapping allow us to, at parsing time, replace a given control type with other control type. The only constrain is that new control type extends primary control type.

If I use Tag Mapping with Web Controls everything works fine but if, instead, I use Html Controls, like HtmlForm, with tag mapping no mapping is done.

Using Reflector I found no reason for this behavior.

Filed in: ASP.NET