• Introduction to ASP.NET MVC – slides and demo project

    I had a presentation last week at MS DevDays Bulgaria and I thought I’d share it with you.

    I was very excited and somewhat nervous - this was my first presentation ever. Nervousness aside, the feeling cannot be compared to anything else – I was glad there are so much people out there who are curious about the topic I’m interested in. It’s a kind of a win-win situation, where the attendees learn something new or see the things from another person’s point of view and the presenter learns even more on the topic from the questions the audience asks.

    Back to the topic:

    Attached are the few slides. As I emphasized most of the code specifics during the demo, I’ll add some more information hereby:

    • The application demonstrates a small forum site. As a model it uses a simple Linq-to-SQL object. The things I stressed were:
    • The declarative approach of specifying routes in the global.asax file;
    • The locations where views are searched (the
      Views/[ControllerName]
      folder and the
      Views/Shared
      folder)
    • The
      ViewPage
      class and its
      ViewData
      property;
    • The
      Html
      property of the
      ViewPage
      class (an instance of
      HtmlHelper
      ), providing a way to have correct URLs even if the requirement for the URL structure is changed:
      • The
        ActionLink
        method;
      • The
        Form
        method;
    • The
      BindingHelperExtensions
      , which can be very helpful when we have a lot of user input to be passed to an object;
    • The ease of writing tests (that became even easier with the latest release) and the red-green testing method.
    P.S. Recently Troy Goode published a very useful ASP.Net MVC Membership Starter Kit you might find interesting.

    Cheers,
    Erjan

  • The dark side of static members

    Often we find it easy to create a class with a static event to keep the controls in our web application loosely coupled. The easiest way to make a number of controls interact without “knowing” about each other is to have a static event distributor class.

    public class EventDistributor
    {
        public static event EventHandler SomethingHappened;

        public static void RaiseSomethingHappened(object sender, EventArgs e)
        {
            if (SomethingHappened != null)
            {
                SomethingHappened(sender, e);
            }
        }
    }

    Some of the controls raise the events of the distributor…

    protected void Button1_Click(object sender, EventArgs e)
    {

        EventDistributor.RaiseSomethingHappened(sender, e);

    }


    …and others subscribe to them

    protected void Page_Load(object sender, EventArgs e)
    {
        EventDistributor.SomethingHappened += new EventHandler(EventDistributor_SomethingHappened);

    }

    The problem

    Let’s say we add an IScriptControl (e.g. from the RadControls for ASP.NET AJAX suite) in the control tree inside the event handler of the static event. After postback we get an InvalidOperationException with the message “Script controls may not be registered after PreRender”.

    The reason

    To find the reason for the error we need to know that static classes and members are alive until the application is restarted. They are not destroyed after the page lifecycle completes. So what happens? A control subscribes to the event of the event distributor in the Page_Load handler. After the postback the event is raised and the control’s event handler method from the first request gets executed. The life cycle of that previous page was already executed and adding a RadControl to the Controls tree will throw the aforementioned exception. This exception is thrown by the ScriptManager control which cannot register script controls after the Prerender event of the Page object.

    There is one more problem here – the event distributor holds a reference to the user control and thus it cannot be garbage collected. This leads to a memory leak on the server.

    The solution

    What we need to do is guarantee that the event distributor does not keep a reference to our object. This can be done easily by detaching the event handler in a later stage of the page lifecycle. Still, this is not the best approach. As the static members are alive as long as the application is, it is possible that concurrent requests to the same page execute simultaneously. This will raise the event twice for both page instances and will execute their event handler methods twice. We can avoid that by making sure our class is page-specific. We can create a singleton static class, which is stored in the Items collection of the Page object and use it. The singleton will be destroyed when the page gets destroyed, so we even do not need the code to remove the event handler.

    I’m attaching a demo project to this post. It contains two folders – one of them contains a page, demonstrating the problem and the other contains the suggested solution.

    P.S. Tess Ferrandez, Microsoft Escalation Engineer describes another drawback of using static members.

    Cheers,
    Erjan
  • Squeezing the last millisecond from the page load time

    Hi, my name is Erjan Gavalji. I am a developer in the ASP.NET division at Telerik. I am new to blogging, but I hope the topics I present will be of a real use.

    RadControls for ASP.NET provide rich client-side functionality and nice look trough a number of external files - JavaScript code and CSS definitions. Those resources are registered through <script> or <link> tags and are downloaded by the browser.

    Part of the client-side code in RadControls “Prometheus” is shared between all controls. It is contained in a different file to prevent downloading it multiple times when several controls coexist in a single page. The scripts of rich controls like RadEditor are split additionally to prevent the output of code that is not used (e.g. there is no need to burden the page with the code for the modules when the control does not have modules enabled).

    The CSS files used by the controls need to be split for the same reason:

    1. each control utilizes specific CSS definitions
    2. different skins of a control have a set of definitions in common

    Having this in mind a page with a RadEditor, a RadMenu, a RadTreeView and a RadGrid renders a pretty large number of <script> and <link> tags.

    In ASP.NET Ajax the ScriptManager handles script resource registration. Embedded scripts (scripts compiled as embedded resources and registered with the WebResourceAttribute) are served by the ScriptResource.axd HTTP handler. The handler identifies the content to serve by a unique URL. When several different controls are used, the total length of webresource URLs increase which affects the page output size and the load time. Also since the browser requests script resources synchronously, each request adds up to the page load time. Last, but not least, Internet Explorer cannot parse more than 30 <link> tags.

    RadScriptManager and RadStyleSheetManager solve the problems described above.

    RadScriptManager is a control, derived from the ASP.NET ScriptManager. While it inherits all the features of its parent, it can combine all the script requests into a single one, thus reducing the page load time as much as possible. It outputs only one <script> tag regardless how many controls are used in the page.

    RadStyleSheetManager provides the same functionality as RadScriptManager, by combining embedded CSS resources.

    Both controls use a custom HTTP handler (similar to ScriptResource.axd) to serve the content. That handler compresses the content with gzip (as ScriptResource.axd does) if the client browser supports that. RadScriptManager and RadStyleSheetManager support caching, because the rendered URL is constant for the same set of controls.

    There is a slight difference between the two controls. While RadScriptManager merges all registered script resources regardless of their origin, RadStyleSheetManager merges only RadControls “Prometheus” embedded skins.

    I created a set of two pages to test the page load time. The first one uses an IFrame to load the second one. The container page measures the content page load time for a specified number of requests with the help of some JavaScript code.

    The table below demonstrates the test results of a page, containing a RadTreeView and a RadMenu instances. The given times are the average of 10 page requests.

    Browser, cache

    Resource combining disabled

    Resource combining enabled

    IE Cache enabled

    145 ms

    135 ms

    IE Cache disabled

    2834 ms

    1101 ms

    FireFox Cache enabled

    386 ms

    378 ms

    FireFox Cache disabled

    2490 ms

    1200 ms

    I’m attaching the test project to the post. If you’re interested in measuring the load times of different control sets, please feel free to modify MainPage.aspx. Please note that to get real-life results you should put the application on a remote server. The net effect of script combining is not that obvious when running on localhost.

    Acknowledgement:

    During the RadControls “Prometheus” development we put a lot of effort researching a way to overcome the limitations mentioned above. While doing our research we found the ToolKitScriptManager, which combines the scripts to a single URL. We followed the ToolkitScriptManager idea. Although we made a different implementation to fit the needs of RadControls “Prometheus”, we’d like to give David Anson the credits for the whole idea behind script combination. He has a very extensive blog post, where he explains the way ToolkitScriptManager works.