I have given here some clues about creating control adapters. A few days after I have started to use them, I have encountered some very special problems. In fact the adapters have the following hierarchy :  the .NET framework expose a ControlAdapter from which derives a WebControlAdapter and a PageAdapter. THe name of these classes being explicit enough to let you know in which cases you should use which one.

As a consequence, when you want to adapt a WebControl, you should use a WebControlAdapter or one of its derived classes. So far, so good, so simple.

But what you should know is that the framework expose in the WebControl class a method called Render. Never seen it or overriden it ? Normal it's a protected internal one. This method is responsible of the rendering of the control and so does : RenderBeginTag, RenderContent and RenderEndTag. And these are the three methods you will normally work with.

And so what does the WebControlAdapter : it will redefine the Render method to do the same work : RenderBeginTag, RenderContent and RenderEndTag. And each of these methods will either call the apdater's equivalent method, or the one of the control itself.

Pretty normal. No problem there.

Well... Almost... Let's imagine just one moment, that someone has defined some other code in the Render method ? Well... That would bring some troubles no ? Right it would break the .NET standard but let's imagine. Of course, in that case, using a WebControlAdapter would just bring a you a no-longer working control.

It's in fact what happens in the BaseValidator class (which inherits from WebControl of course). The Render method does a lot more, like rendering javascript, the "display" and "visibility" attribute.

Which conclusion, what can we say now ? Never use a WebControlAdapter when working with a BaseValidator (or any derived class). Prefer working with a ControlAdapter instead !

Some explanation 

Depending of the browser, some control may need to be rendered differently. By default the .NET framework works with "Control Adapters", id est, some classes that will be plugged into the rendering process.

How does it works ? When the server receives a request, it will try to find which browser does the request, based on the user agent or on HTTP headers for example. To do it rely on some browser definition files (of extension .browser). To see them, please go on %windir%/Microsoft.NET/Framework/<version>/CONFIG/Browsers.

When the server has identified the browser (at worse, it would be identified as a "Default" browser), and that it needs to render a control, it will look if there is some control adapters plugged for this kind of control. If there are some, they will be in charge of the rendering. If not, the control will render himself. Note that an adapter can redirect / delegate some treatment to the control.

Creating a basic Adapter for TextBoxes

  • Let's create a solution with a website and a "Web Control Class Library" (named "MyControlLibrary")
  • Let's add a new class in the library for the adapter. Note that by convention, an adapter will always be named "ControlNameAdapter" where "ControlName" is the control we want to adapt. Here we'll so create the "TextBoxAdapter"

using System;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.Adapters;

 

namespace MyControlLibrary

{

   public class TextBoxAdapter : WebControlAdapter

   {

      /// <summary>

      /// If you need to access the adapted control, the framework advice to expose

      /// a private method encapsulating the Adapter's Control property.

      ///

      /// We can cast it without doing any test, as by naming convention,

      /// this adapter shall only be used for adapting Textboxes (or derived types)

      /// </summary>

      private TextBox Control

      {

         get { return (TextBox)base.Control; }

      }

 

      /// <summary>

      /// Let's add some extra attribute in our control's begin tag

      /// </summary>

      protected override void RenderBeginTag(HtmlTextWriter writer)

      {

         writer.AddAttribute("MyNewAttribute", "This has been set in the adapter");

         writer.AddAttribute("ControlType", this.Control.GetType().FullName);

 

         base.RenderBeginTag(writer);

      }

   }

}

How to use it in a website ?

The mapping between a control and its adapter is done at the website level, using the browser definitions.

  • In the website, add the special folder "App_Browsers"
  • In the folder add a new browser definition file

We have several solutions here. The simplest is to add some capabilities to an existing browser. We can either decide to do this for all browser, or for a specific browser.

<browsers>

<!--

   Here we extend the "Default" browser (ie the basis browser from which all other

   browser derive (see in %windir%/Microsoft.NET/Framework/<Version>/CONFIG/Browsers)

 

   To extend only a specific browser, replace the refID by another one eg :

      refID="IE" for all versions of IE

      or refID="IE50" for only the 5.0 version

   -->

   <browser refID="Default">

      <controlAdapters>

         <adapter adapterType="MyControlLibrary.TextBoxAdapter"

                  controlType="System.Web.UI.WebControls.TextBox" />

      </controlAdapters>

   </browser>

</browsers>

How to use this functionality for testing purposes ?

Let's explain my context : in a TDD environment all code (and so pages) are tested before being written. To do so, we can use for instance basic HTTP request that will call my page and then validate them using any HTML parsing. In order to facilitate the testing, we may want to base our research on some extra tags. That's where Control Adapters may enter in the game. As a consequence we want some control adapters to be used only for testing. The simplest way to do so is to consider that our testing framework will use a "special browser" by giving some clues in the HTTP Headers or in the user agent.

For example by using this code, we could make request by simulating a IE 5.0 browser, and sending an extra hint.

HttpWebRequest request = HttpWebRequest.Create("http://localhost/MyPage.aspx")

   as HttpWebRequest;

request.UserAgent

   = "Mozilla/4.0 (compatible; MSIE 5.0; Windows 95; MyTestSimulator)";

At the end, we could update our browser file to have this kind of definition :

<browsers>

   <!-- Let's create a new browser, extending another one,

   eg IE50, Mozilla, MozillaFirefox, Default, ... -->

   <browser id="MyTestSimulator" parentID="IE50">

      <!-- Let's here base our research on our user agent hint to match our

      "special test browser"

      -->

      <identification>

         <userAgent match="MyTestSimulator" />

      </identification>

 

      <controlAdapters>

         <adapter adapterType="MyControlLibrary.TextBoxAdapter"

                  controlType="System.Web.UI.WebControls.TextBox" />

      </controlAdapters>

   </browser>

</browsers>

To conclude my Tech Days 2008 posts, I wanted to add a section with the list of question I have asked to the different speakers and their answers.

  • Ingo Rammer - after the "Advanced Debugging" Session
    • For debugging purposes, I have been working with the Performance tools of Visual Studio and I have experience some strange behaviors : when trying to visualise the function call tree to see which par of my code was taking long, I could not visualize the full call tree. Do you have seen any limitation on this tool that could explain this problem ?
      • Unfortunately, I mainly work in "Production Debugging mode" where I don't have any Visual Studio installation available and so I don't know very well the performance tools of Visual Studio.
    • And when you need to trace performance of you application, which tool do you use ?
      • There is the tool of RedGate (Note : ANTS), but I don't like it so much. I prefer using dotTrace  
  • Nikhil Kothari - after the "Ajax Patterns" Session
    • I have been really interested by the last part of your demo, using Silverlight to read a client file. Is there currently any poossibilities for Silverlight to interact with client resources ? eg getting access to a card reader ?
      • Currently only the ReadFile function allow to access client resources. So unless the card reader allow this kind of API, no it's not possible.
    • Do you know if there is something planned ?
      • There are of course improvements planned for Silverlight, but I don't know if this kind of enhancements is foreseen  
  • Jelle Druyts - after the "Domain-Specific Developments with Visual Studio DSL Tools" Session
    • I have been workinng with the DSL tools but a very long time ago and I am curious to compare what I have seen at this time - when it was immature - and now. Does the T4 template files are still shipped with a model ? (and so copied multiple times for each solution we will use the DSL tool ?)
      • Unfortunately yes. This does not really makes sense and moreover it does complicate any patch or upate to the tool. But what is possible - and what I have done for the Configuration Section Designer - is to provide a very small  T4 template file that will just link to the real file, installed in a common location, eg in the program files folder.
    • And can the T4 templates generate now multiple files ?
      • No still not. It's a pity because it could me more readable (Note : even if the generated files should not be read) to generate several files, and also in different locations, as for example in different projects to allow a full separation of concerns. This will probably arrive in the future.
    • And do we still have the limitation to have only one model by project ?
      • No. The transformation is based on file extension. As a consequence, we can now have as many model as we want.
  •  Roy Osherove - after the "Deep Reflection" Session - Get the slides here
    • I'm curious to know, when you would generate IL at runtime using the techniques you have shown, and when you will use an AOP framework to do the same at compile time ?
      • Well I have never been needint to use an AOP framework. But anyway philosophically speaking, I would never generate IL at runtime Laughing
    • Laughing Honestly me neither. But sometimes we need Smile
    • I wanted also to re-ask the same question about the performance tools that I haved asked to Ingo Rammer, but I got the same answer.
    • And are you still working on "the Regulator"

Thanks all to all theses comments ! I would have liked to speak more about the sessions, but the schedule is so fast we couldn't continue. But great event, and great speakers !

And here is the summary of the last day of the Tech Days. Definitely too short !

Session 1 : ASP.NET MVC Framework (By Matt Gibbs)

Find some information on Scott Guthrie's blog, or download it here

Matt Gibbs has presented today this new framework designed by Phil Haack (for which no shipping date has been planned) that should enforce the separation of concerns. Some key points ?

  • The DLLs have been reorganized and for exemple the new System.Web.Routing.dll could be used for another project, as for example for the Dynamic Data Framework?
  • Creating a MVC project will generate a new test project and we can decide to use some other tools like Brail for the Views or NHibernate for the Models
  • The page in the MVC model will not contain any form. As a consequence, some controls will not be used (all the controls doing postbacks, the UpdatePanel, ...)
  • Some constraints can be set on the routes using regular expressions

Session 2 : Domain-Specific Development with Visual Studio DSL Tools (By Jelle Druyts)

Jelle Druyts has presented the DSL tools by presenting its project Configuration Section Designer that will help creating class for reading sections from the config file. Note that it will also generate an XSD for having intellisense.

  • He has presented quickly the different Software Factory Technologies
    • Visual Studio Templates
    • Modeling Tools (in the Team Edition for Software Acrhitects)
    • The Guidance Automation Toolkit
    • The DSL tools
  • The DSL authors will need the Visual Studio 2008 SDK. Note that the DSL consumer will need a normal VS 2008 installation (it was not the case in VS 2005)
  • He has shown the use of "Bring Tree Here" in the DSL designer
  • He has explained the two views to define in the designer : the domain model and the shapes, and has shown the mapping between the two in the designer
  • Explanation of the constraing (soft or hard) by using some exceptions or some rules
    • Note that a soft rule will allow to persist the model but will block at validation time
    • The constraint can be done using a partial class : PropertyHandler and overriding a OnValueChanged method

Inspiration Session 2 : Fun In .NET (By Chad Hower - website : Woo-Hoo)

Well... Fun indeed but not of great interest. Ok we can control Powerpoint or a rocket launcher with a WIImote... Cool but what for ?

Chad Hower has also presented quickly COSMOS - its C# Open Source Managed Operating System.

Session 3 : Custom LINQ Providers - LINQ to anything (By Bart De Smet)

Crazy Session ! Very exciting !

  • Started with a quick C# 3.0 test
    • I have learned that when using anonymous types, a temporary variable will always be used to guarantee atomicity
  • Given some existing LINQ provider
    • LINQ to Flickr
    • LINQ to Desktop Search
    • LINQ to File System
    • LINQ to Sharepoint
  • Quickly explained the two query sources
    • IEnumerable -> will be transformed in anonymous methods
    • IQueryable -> will provide an Expression Tree
  • Precised that the transformation from LINQ to "code" will not necessarily search for extension methods. We can use some instances methods
  • Explanation of how to create a IQueryProvider
    • Note that the Execute method will be called only when a single result will be returned like when calling .Single, .First, .Default, ...
    • Note that "Linq to AD" support only Select and Where mehods
  • Demo of the Debugger Visualizer to see the Expression Tree
  • Note that there are some Extensions classes (SqlMethods, CamlMethods) to expose some functionality of a richer target language
  • He has described some difficulties of the transformation from an expression tree to the target language
    • having a client doing .ToString().ToString().ToString()...
    • having several syntax leading to the same things like "a" == "b" and "a".Equals("b") and string.Equals("a", "b") and ...
    • Bart De Smet is now working on a tool to normalize an expression tree

Session 4 : .NET 3.5 : Winforms & WPF (By Chad Hower - website : Woo-Hoo)

Once again, It didn't caught my eye. He has presented the strengh and weakness of the Winforms and of WPF

  • Winforms
    • Strength
      • Familiar
      • Many Controls
    • Weakness
      • No stylable
      • No flows, too many tabs
      • Different APIs for integrating audio, video, ...
  • WPF
    • Streangth
      • Stylable
      • Single API for integrating audio, video, ...
      • XAML like Silverglight
    • Weakness
      • We need to re-learn
      • We still need to work in XAML (some things cannot be done at design time)
  • There will be an update to VS 2008 during the year to improve the WPF designer
  • There are some converters
    • Winforms to XAML
    • PPT to XAML
    • Adobe and Flash to XAML

Session 5 : Deep Reflection (By Roy Osherove)

Great conference !

  • In the case of clone or serialization, there are two solutions
    • Doing by reflection
    • To Emit a method, method that will be called in the future
  • Explanation of the CodeDOM
  • Explanation of Reflection.Emit
  • Explanation of the Lightweight Code Gen (LCG)
    • With DynamicMethods, we can use SkipVisibility="false" to improve performance : the CLR will not test the visibility of the called members
    • DynamicMethods are garbage collected
    • We can create a delegate from a DynamicMethod
  • Quick demo of RunSharp that can ease the emit
  • Explanation of the ReflectionOnly mode to avoid being exposed to malicious code and some of the methods
    • Assembly.ReflectionOnlyLoad
    • Type.ReflectionOnlyGetTypes
    • CustomAttributeData.GetCustomAttributes
  • Explanation of how to create and compile an expression tree

Unfortunately, due to my spanish course, I could not see the Closing Keynote. But anyway, it was a great year. I will just regret that there was so few time between each session so I could not speak enough with the seakers I wanted to see or with other people present there I wanted to see.

Here is a little summary of the sessions I have been able to attend on this day:

Opening Keynote (By Rafal Lukawiecki)

Definitely an interesting speaker. Pity I was not ideally seated to hear and see good, and that I had not been able to see him another time during these days. He has been presenting a bit of past and future for development

He has been presenting a comparion between Imperative and Declarative programming languages and the evolution of application with Service Brokers and composite applications. He has also spoken a bit of "OSLO", the future - in his view - for developping software as a model, using Declarative Model Composition in order to achieve a seamless runtime hosting and deployment.


 Session 1 : WCF & WF - Integrating two key technologies of .NET 3.5 (By Ingo Rammer)

Interesting session ! Above the fact I like this speaker, it continues the talk his colleage Christian Weyer had last year. In 2007, Weyer has presented the different problems - and immaturity of the products. This year, Ingo Rammer emphasizes on the evolutions and the different scenaris for integrating the technologies.

  • Recall of the WCF's ABC (Address, Binding, Contract)
  • Presentation of 3 scenaris
    • Regular Service
    • Durable Service
    • Workflow Service
  • Explanation of how a duplex contract work and what are the limitation of the Duplex Channels (life duration of the channel : life duration of the application itself)
  • Explanation of how to put in place Durable Services to achieve statefull (and sherver-shutdown resistant) services using the
    • DurableServiceAttribute
    • DurableOperationAttribute
  • Explanation of the durable operation services persistance bahvior
    • when it starts
    • when it stops
    • how to configure it using the providers in the config file
    • how to configure the database using the scripts provided by the framework under c:\windows\microsoft.net\framework\v3.5\SQL\en-US
  • Presentation of the same scenario, but integrating a workflow, explaning the two ways of working : "workflow first" or "contract (interface) first"
  • Explanation of the two new "Send" and "Receive" activities and of the "ListenActivity"
  • Shwoing some debugging possibilities inside of a workflow

This session was interesting but a bit hard to follow as I don't have yet sufficient knowledge in WCF and WF.


Inspiration Session 1 : ASP.NET Futures (By Matt Gibbs)

No lunch time this year, but instead an extra session that I don't regret I went.

Matt Gibbs has focused this presentation on the Dynamic Data Framework (which is also a good start point for the ASP.NET MVC framework).

  • Demo of how to create a Data-Driven Web Application using Dynamic Data
    • How to create a model using LINQ to SQL
    • How to configure the application (via global.asax to register the DB context
    • Demo of the generated website with the different tables and the following capabilities:
      • Sorting and Filtering
      • Adding, Updating and Deleting
      • RelationShips being understood
      • Validation done, based on the model (required or not, type, length)
      • Ajax integration
  • Explanation of how to customize the result
    • Use of a partial class of the model to use some "MetaDataTypeAttribute" to add extra validation for example
    • Create a new "Fied Template" to show some special controls for some types or properties and make the link to a partial class using a UIHintAttribute
    • Create a new "Custom Page" for a specific table name
    • How to use Routing for special navigation / routing instructions 

30mn to present quite in-deph the framework... Quite intense. Hopefully I had already seen part of this typical MS presentation on many other blogs (like among others http://www.loicbar.com/)


Session 2 : Building Applications with Silverlight 2.0 (By Nikhil Kothari)

  • Quick presentation of some features
    • Cryptography API
    • Threading support
    • Sandboxed execution
    • 4Mo size client download, including multi support browser
  • and information about the Silverlight 2 SDK including
    • the new controls (like FormsControl, DataGrid)
    • Syndication
    • XML Serialization
    • Will be shipped in Beta2 (with Go-Live licence) in Q2 2008
    • Expression Suite and Visual Studio will be updated at that time to allow a nice integration experience
  • Explanation that a Silverlight app is hosted in a website, via a compiled ".xar" file
  • Demo of the XAML code-behind files and of the initialization of the application that may (re)load saved properties from client disk
  • Demo of how to save and load client specific data using the System.IO.IsolatedStorage namespace
  • Demo of how to manipulate the Browser (HtmlPage.Windows.Navigate) for redirectind

Session 3 : Advanced debugging using Visual Studio (By Ingo Rammer)

This session is following the one he has done in 2007 (Hardcore Production Debugging - PPT) but focusing on the tools available in Visual Studio.

  • Presentation of the different capabilities of the BreakPoint (conditional or not, hit count, based on a method name, wherever it is, ...)
  • Presentation of the Debugger class, more specifically the Debugger.Break() and Debugger.IsAttached
  • Presentation of the Trace Point (Breakpoint using the option - when hit) to use macros to dump the stack trace for instance
  • Presentation of the Command Window with the aliases
  • Presentation of the Watches
  • Presentation of some debugging-related attributes like DebuggerDisplay, DebuggerTypeProxy and DialogDebuggerVisualizer
    • Note that for the two lasts, the target object must be serializable
    • The attributes can be set at object level, or at assembly level
  • Presentation of the Immediate Windows
  • Presentation of the Object Test Bench, from a class diagram
  • Recall of the rules to have a good "debuggability" in a project like
    • Avoiding non-essentials exceptions (by using TryParse, ...)
    • Catch exception when you handle it
    • Throw essential exceptions
      • Use throw; and not throw ex;
  • Quick presentation of MDbg to exttract some information when an application crashes (can be used in production)

Definitely a passionated (and passionating speaker). Thanks Ingo


Session 4 : Sql Server 2008 - What's new for Developpers (By Dandy Wein)

The presentation has focused to the T-SQL enhancements

  • Date and Time types and DateTime2 type with the new precision
    • from 1/1/1 to 31/12/9999 with a precision to 100 nanoseconds
    • DateTimeOffset type and SYSDATETIME function
  • Localization capabilities using the SET DATEFORMAT and SET LANGUAGE prerogatives
  • Demo of the new Table-Valued parameters to avoid doing too many queries when dealing with tables with 1..n relationship
  • Being able to declare and initialize a variable on the same line : DECLARE @myInt INT = 10
  • Increment operators : SET @myInt += 1
  • Row constructors : being able to insert several rows at the same time
  • INSERT INTO MyTable(Col1, Col2)VALUES(1, "Val 1"), (2, "Val 2"), (3, "Val 3"), (4, "Val 4")
  • The COMPUTE BY statements are now deprecated and will be replaced by some GROUPING SETS instructions (WITH CUBE and WITH ROLLUP remain)
  • A new MERGE instruction has been added to facilitate merge vetween tables
  • HIERARCHY and HIERARCHYID have been added to facilitate the recursive queries
  • New spatial data and functions (to see for example if a certain point is present in a given region, ...)
  • A new FILESTREAM object : when storing some files in a table, we'll know declare them as "VARBINARY(MAX) FILESTREAM" to improve performance and avoid DB fragmentation. Note also that the DB Server will no longer limitate the size of files (it was 2Go before)

Session 5 : Ajax Patterns (By Nikhil Kothari)

The goal of the presentation was to show all the challenges we were facing when working in a AJAX application and how we could resolve them. He has shown among all :

  • How to call a web service from javascript using a ScriptServiceAttribute, after having registered it in the ScriptManager
  • The difference (in performance) between an UpdatePanel and calling a web service directly (and so using JSON)
  • How to create an AJAX control behavior
  • How to provide good navigation and bokkmarkability by updating the url and adding steps to the history using the addHistoryState
  • How to provide Indexability on a page by providing static data
  • Demo on the integration of a Silverlight app in an ASP.NET with AJAX, and showing how to call a OpenFileDialog from Silverlight

 

Quite an interesting day !