Wednesday, December 13, 2006

How to use ASP.NET controls inside a XSLT

I wrote an article at CodeProject explaining how to use ASP.NET controls inside a XSLT.

I think that this is a must read to anyone that uses XSLTs in their web applications and even to every ASP.NET developer!

Brief description of the solution

I used a HttpModule to capture all requests made to all ASP.NET pages and made the XSLT/XML transformations before the request arrives at the PageHandlerFactory, in the HttpPipeline, and the ASP.NET page is dynamically created.

I have a demo project showing this solution, but if you want to look only at the HttpModule’s code, I’ve posted the source code of the HttpModule only as well.

Read the article and leave a comment!

Tell me what you think!

Read the article here

Posted by BCoelho2000 at 22:52:07 | Permalink | No Comments »

Tuesday, October 10, 2006

The Garbage Collector, the JIT compiler and ASP .NET Code-Behind

Introdution

In this article, I will start by talking about the .NET’s garbage collector. Then, I will give you a strong reason for using the code-behind technique of ASP .NET.

Automatic Memory Management

One of the CLR features is the automatic memory management mechanism. With automatic memory management, the developer doesn’t need to track memory usage and know how or when to free memory.

To create an object you use the new operator and… that’s it. When you don’t need to use that object, you simply stop using it. Using other words, you stop using the reference to that object.

But since you have no control on how and when the memory of the object will be reclaimed:

  • How do we know if there is enough memory for creating that object?
  • How about the object’s unmanaged resources?
  • How do we know if the object is still alive?

How do we know if there is enough memory for creating that object?

The advantages of creating objects in the managed heap exist because the managed heap makes an important assumption: the address space and storage infinite. It can make this assumption because of the existence of an important CLR mechanism called the Garbage Collector.

Introducing the Garbage Collector (GC)

The CLR has a mechanism called the Garbage Collector to manage the memory in the managed heap.

When there’s no memory left for creating a new object in the managed heap, the gc will stop the program’s execution and will start looking for objects that aren’t referenced by roots(*1). A root is a storage location containing a memory pointer to a reference type object. If the object isn’t referenced by any root that object will be considered garbage and it’s memory will be freed.

How about the object’s unmanaged resources?

Sometimes, stop referecing an object and let the garbage collector reclaim it’s memory isn’t enough. Consider if the object wraps some unmanaged resources (e.g: files, database connections). Before having it’s memory freed it should release it’s unmanaged resources.

For an object have the capabilty to deterministically dispose an objct, it must implement the dispose pattern.

To implement the dispose pattern the type must implement the IDisposable interface defined in the FCL. It should define a public, parameterless Dispose method that can be explicitly called to release any unmanaged resources wrapped by the object. However, the memory is still being managed by the GC, i.e, the memory will only be freed in the next garbage collection.

How do we know if the object is still alive?

In fact, an object isn’t garanteed to live till the end of the scope of a method.

Yes, it’s true.

Let me show you one of the wonders of .NET’s CLR.

The JIT compiler and the GC

The JIT compiler translates the intermediate language (IL) into native code.

Consider this code:

void SomeMethod()
{
  SomeHeavyMemObject sho = new SomeHeavyMemObject();
  ...
  sho = null;
}

When the JIT compiler compiles the IL for a method into native code, it checks to see if the assembly defining the method was compiled without optimizations and if the process is being executed under a debuffer.

If both are true, the JIT compiler will artificially act like the SomeHeavyMemObject must until the end of the method. The JIT compiler does this to make possible JIT debugging. Imagine trying to debug a program just to find out that the variable that you wanted to see was garbage collected!

Else, the JIT works as an optimizing compiler. So as soon as you stop to reference a variable, that variable is considered garbage and it’s memory will be reclaimed at the next garbage collection. In fact, setting SomeHeavyMemObject to null is the same as not reference it at all.

Now let’s see one more reason for using the ASP .NET’s code-behind technique.

Why you should use ASP .NET Code-Behind

Imagine that you have an object in your SamplePage class called SomeHeavyMemObject. Imagine that you don’t care about using the ASP.NET’s code-behing techique and you use the following code:

public class _Default : System.Web.UI.Page
{
  protected SomeHeavyMemObject sho = new SomeHeavyMemObject();

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

In the .aspx.cs

<%=sho.GiveSomeHtml()%>

In the .aspx

Now remenber that ASP.NET pages are always compiled into .NET classes housed within assemblies. This class includes all of the server-side code and the static HTML, so once a page is accessed for the first time subsequent rendering of that page is serviced by executing compiled code. That particular line of code is going to be placed inside the Render method of our page derived class.

That is a major disadvantage.

Think about it…

Even if you compile your page with optimizations, the variable SomeHeavyMemObject must live at least until it’s GiveSomeHtml method is called inside the Render method. Only then the GC could collect it’s memory.

It’s even worse, if SomeHeavyMemObject wraps some unmanaged resource. If it was true, you could only call the Dispose method in the UnLoad event of the Page, making the object live until that point.

Now, if you choosed to use the code-behind technique:

public class _Default : System.Web.UI.Page
{
  protected System.Web.UI.WebControls.Literal literal;

  private void Page_Load(object sender, System.EventArgs e)
  {
    using(SomeHeavyMemObject sho = new SomeHeavyMemObject())
    {
       literal.Text = sho.GiveSomeHtml();
    }
  }
}

In the .aspx.cs

...
<asp:Literal runat="server" id="literal" name="literal"/>
...

In the .aspx

Using this technique the SomeHeavyMemObject only lives the exact time that it needs and it’s unmanaged resources will be collected by the end of the Load method. Also, if there’s a garbage collection SomeHeavyMemObject will be considered garbage and it’s memory will be freed.

Conclusion

We’ve seen how the GC works and how the JIT compiler knows when you stop using your reference type variables. Using that knowledge we’ve seen how using the code-behind technique can optimize memory usage.

*1 - This is a simplification. The CLR’s Garbage Collector is a generational collector, that is, every time a new reference type object is created it will go to the Generation 0 (Gen 0). When Gen 0 is full, the program execution will stop and a collection will take place. The objects that survived the collection will be promoted to the Gen 1, and so on. The CLR’s Garbage Collector has up to 3 generations.

Posted by BCoelho2000 at 00:17:59 | Permalink | No Comments »

Tuesday, September 19, 2006

HttpModule remove bug Part 2 - The workaround

Well, I’ve found a way for not loading the HttpModule, using the web.config <remove … >, but it isn’t pretty…

How?

You still have to put the HttpModule’s assembly inside the bin/ directory of the child web application and add the remove element for HttpModules in the web.config.

Then, the reference to the HttpModule will be removed.

Undocumented feature

The documentation MSDN doens’t say anything about explicitly putting the HttpModule’s assembly inside the bin/ directory, of the child web application, EVEN if you don’t want to use it.

If the the remove element for HttpModules was created like the remove element for HttpHandlers we wouldn’t have this problem, because the remove element for HttpHandlers has an attribute called path. There you can set the path to the HttpHandler that you want to remove…

Who said that life was fair anyway?

See you next time!

Posted by BCoelho2000 at 21:14:13 | Permalink | No Comments »

Sunday, September 17, 2006

HttpModule remove bug - ASP .NET 1.1

Hi everyone!

This time, I’m here to warn you of a bug in ASP .NET 1.1.

The scenario

Let’s say that you have a web application. Let’s called HttpModuleIssue. That web application has a child web application that I’ve called HttpModuleIssueSubApp.

Let’s look how this is configured in IIS.

Each one of this web applications has a Web.Config file.

Quick Web.Config talk

A web.config file is, has you know, a special file where you can manage the configuration of your application.

The root of the ASP.NET configuration hierarchy is a file referred to as the root Web.config file, and it is located in the same directory as the Machine.config file. The root Web.config file inherits all of the settings in the Machine.config file. The root Web.config file includes settings that apply to all of the ASP.NET applications that run a specific version of the .NET Framework. Because each ASP.NET application inherits default configuration settings from the root Web.config file, you need to create Web.config files only for settings that override the default settings. More info here.

Adding a HttpModule

Let’s add a HttpModule to our main web application HttpModuleIssue.

The HttpModule doesn’t do anything usefull… it’s only to show you the dreaded bug. Anyway, here it is:


using System;
using System.Web;

namespace HttpModuleExProject
{
    ///
    /// Summary description for HttpModuleEx.
    ///
    public class HttpModuleEx: IHttpModule
    {
        public void Init(HttpApplication app)
        {
            // Register for pipeline events
        }

        public void Dispose()
        {
            // Nothing to do here
        }
    }

}

 


Now, not only do we have to put the assembly of our HttpModule inside the bin directory of HttpModuleIssue, but we must also add an entry to the HttpModuleIssue’s web.config file registering the HttpModule.


<system.web>
    <httpModules>
        <add name="HttpModuleEx"
             type="HttpModuleExProject.HttpModuleEx, HttpModuleEx" />
    </httpModules>

The name attribute can be any name that we like. The type attribute must be in the format “namespace.typeName, typename”.

This works with no problems. But if you visite a page inside the web application HttpModuleIssueSubApp, you will see this runtime error:

Well, after our previous web.config talk, that should be expected. After all, HttpModuleIssueSubApp doens’t want to use that HttpModule, but it’s web.config file inherits the registration of the HttpModule.

The solution that should work

According to the documentation you can remove the HttpModule that some parent web application might have registered. It should be as simple as putting the following code inHttpModuleIssueSubApp’s web.config file:


<system.web>
     <httpModules>
        <remove name="HttpModuleEx" />
    </httpModules>

The sad true

Unfortunately, it doens’t work at all. The runtime error still happens. I’ve seen a couple of developers complaning about this issue… This issue was found using ASP.NET 1.1.

The sad solution

The only solution is copying the HttpModule assembly to the child web applications…

You can download the source code used for this article here.

Any comments about this bug/issue are appreciated.

See you next time!

Posted by BCoelho2000 at 08:44:18 | Permalink | Comments (1) »