Alik Levin's

Clarity, Technology, and Solving Problems | PracticeThis.com 

December, 2007

  • Alik Levin's

    ASP.NET AJAX Control Toolkit - Basic Sample For DynamicPopulate Control

    • 6 Comments

    How to dynamically populate the content of a control based on Web Service call triggered by another control? DynamicPopulate extender to the rescue:

    DynamicPopulate is a simple extender that replaces the contents of a control with the result of a web service or page method call. The method call returns a string of HTML that is inserted as the children of the target element.

    This post to summarize basic steps of using AJAX Control Toolkit's DynamicPopulate extender. Plus customer's case study of how it was implemented with ASP.NET Masterpage for performance and UX improvement.

    Summary of steps

    • Step 1 - Create ASP.NET Web Application
    • Step 2 - Add server side code
    • Step 3 - Add DynamicPopulate extender
    • Step 4 - Add client side script to use the extender behavior
    • Step 5 - Add client side event to invoke the client script
    • Step 6 - Test the solution

    Following section describes each step in details.

    "Then another ask came through - content page must update the sidebar that is part of the Master page...."
  • Step 1 - Create ASP.NET Web Application. Open Visual Studio 2008. Create new "ASP.NET Web Application" project, found under Web node in "New Project" dialog. Name it DynamicPopulateSample. Add site's Master Page by right clicking on the project in project explorer window, then "Add" ->  "New Item...", then choose "Master Page" template from the "New Item" dialog. Leave its default name. Drag Label control on the Master page from the Tool Box. The Label will be dynamically updated. Add new ASPX page by right clicking on the project in project explorer window, then "Add" -> "New Item....", then choose "Web Content Form". Specify it's Master Page by choosing Site1.Master. Name it default.aspx. Add two pure Html radio buttons to default.aspx. These will serve as a trigger to update the Label on the Master Page. Add AjaxControlToolkit.dll to the project's  bin folder and add reference to it.
  • Step 2 - Add server side code. Open default.aspx.cs code behind for default.aspx. Add the following function:
    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public static string GetHtml(string contextKey)
    {
        // A little pause to mimic a latent call
        // This is the place to perform server side
        // code like DB access
        System.Threading.Thread.Sleep(350);
    
        return String.Format("Persona: {0}", contextKey);
    }
  • Step 3 - Add DynamicPopulate extender. Register AjaxControlToolkit assembly inside the page. Add the following declaration right after <@Page...> directive 

    <%@ Register
       
    Assembly="AjaxControlToolkit"
       
    Namespace="AjaxControlToolkit"
       
    TagPrefix="ajaxToolkit"%>

    Add AJAX Script Manager to the page: 
    <asp:ScriptManager ID="ScriptManager1"runat="server"/>

    Add DynamicPopulateExtender control to the page:

      <ajaxToolkit:DynamicPopulateExtender
             
    ID="dp"BehaviorID="dp1"runat="server"
             
    TargetControlID="form1$Label1"
             
    ClearContentsDuringUpdate="true"
             
    ServiceMethod="GetHtml" />

    Notice TargetControlID is set to "form1$Label1". This is the Label control to be updated with the Html string returned by the server side code I described in Step 2. $ notation means nesting - read "Label1 control inside form1 control". It can be any nesting depth. Save your work and then view in browser to make sure that no exceptions generated.

  • Step 4 - Add client side script to use the extender behavior.  So far, there is Label1 to be updated and it is sitting in the Mater page. There is DynamicPopulateExtender that defines the behavior. There is server side code to handle the request. Now add client script that makes the request to the server:

    <script type="text/javascript">
            function
    updateDateKey(value) {
                var behavior = $find('dp1');
                if(behavior) {
                    behavior.populate(value);
                }
            }
            Sys.Application.add_load(function(){updateDateKey('Alik Levin');});
        </script>

    Notice initialization function call - the last row. It invokes the client side function to call into server side for the first time when the page is rendered into the browser for the first time.

  • Step 5 - Add client side event to invoke the client script. The last part is adding the event that triggers the client side code to be invoked and thus making call to the server. Locate Html radio buttons that were created during Step 1, add onclick events to call the client side function:
    <input type="radio" 
           name="rbFormat" 
           id="r0" 
           value='alik'
           onclick="updateDateKey(this.value);" 
           checked="checked" />click to set 'alik'<br/>
    <input type="radio" 
           name="rbFormat" 
           id="Radio1" 
           onclick="updateDateKey(this.value);"
           value='levin' />click to set 'levin'
  • Step 6 - Test the solution. Save your work and view in browser. Click on the radio buttons and you should see how the Label in master page gets updated with respective values. It all happens with small delays simulated on the server by Sleep function. I think it is cool.
    • Case Study

    I was asked by a customer to offer a solution for very responsive UX [User Experience] while avoiding annoying refresh of the web page. Natural answer was AJAX. The customer also asked to provide the solution for common look and feel. Master pages was my answer. Then another ask came through - content page must update the sidebar that is part of the Master page.... hmm A-ha! Use DynamicPopulateExtender.

    My Related posts

    Sample VS2008 project that demonstrates DynamicPopulateExtender can be found on my SkyDrive:

     

    Watch UX [User Experience] in the video below:


    Video: DynamicPopulateExtender Demo

    Enjoy.

  • Alik Levin's

    Basic HttpModule Sample (Plus Bonus Case Study - How HttpModule Saved Mission Critical Project's Life)

    • 1 Comments

    This post to describe basic steps to write HttpModule and how it rescued mission critical application from not hitting the dead line.

    HttpModule is the mechanism that facilitates implementing cross cutting logic for incoming ASP.NET requests. ASP.NET uses it extensively under the covers for its needs too - Session management, Authentication to mention a few. What I love most with HttpModules is that there is no need to alter the application itself - just implement IHttpModule interface and tweak web.config. That is all.

    Steps to build HttpModule

    • Step 1 Create Class Library
    • Step 2 Implement IHttpModule Interface
    • Step 3 Configure ASP.NET application to use HttpModule
    • Step 4 Test the application

    Next section describes each step in detail.

    "no need to alter the application itself - just implement IHttpModule interface and tweak web.config"
  • Step 1 Create Class Library. Fire up Visual Studio. Click "New Project" dialog, click "Visual Studio Solutions" choose "Blank Solution" and create empty solution. Name it HttpModuleSample. Right click on the solution in "Solution Explorer" and then click "Add", "New Project...". Choose "Class Library" template and name it MyHttpModuleLib. Delete default Class1.cs. Add reference to System.Web assembly.
  • Step 2 Implement IHttpModule Interface. Add new class to the project and call it MyHttpModule. Add using System.Web declaration. Implement the IhttpModule interface just add :IHtpModule and let Visual Studio implement it explicitly. Register for any of ASP.NET pipeline events - BeginRequest for example - in Init(...) method. Set break point in the event handler.

    image

  • Step 3 Configure ASP.NET application to use HttpModule. Right click on the solution in solution explorer and add new "ASP.NET Web Application" found under Web node in "Add New Project" dialog. Name it HttpModuleTestWeb. Open the application Web.Config file and add HttpModules node in case it is not already there: image Configure MyHttpModuleLib project output path to HttpModuleTestWeb's bin folder. To do so right click on MyHttpModuleLib and choose properties, go to Build section and then to "Output path" in out put section: image Build the solution. Ctrl+Shift+B.
  • Step 4 Test the application.  Set HttpModuleTestWeb as start up project and hit F5. You should hit the break point set inside the HttpModule even before the Web Application's page was accessed: image 

    Here I implement any logic I want to run before the page got hit. HttpModule serves as a filter or gatekeeper for incoming Http requests. Following case study explains how such approach saved mission critical application.

  • Case study

    Critical mission application was to go live in few days. The schedule was tight. All functional and integration tests went well. The last one was load and stress tests. During the the load test turned out that one of the network components was crashing as a result of memory leak. The component was sending http headers. We decided to configure the component to send the data in Query Strings instead Http Headers [making story short...]. We needed to find the way to teach the application to look the data in Query Strings instead Http Headers. HttpModule to the rescue!! We developed simple HttpModule that was hijacking the request, scrapping the Query String and setting the data inside Http Headers, where the application was looking for it. Heaven. Worked like magic.

    Caveats

    Adding Http Headers in .Net is not straight forward since the collection is read only. Reflection to the rescue! Following code explains how to hack Http Headers collection to make it writable - http://forums.asp.net/p/979853/1250479.aspx#1250479. Then we needed to drop the extra Query String before it got to the application. My search landed directly to ScottGu's RewriteUrl post - http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx. What's left is make reflection run faster by caching type's constructor as described here - http://weblogs.asp.net/bradygaster/archive/2003/11/26/39952.aspx

    My Related posts:

    Sample VS2008 project can be found on my SkyDrive:

  • Alik Levin's

    ASP.NET 3.5 Extensions: Basic Steps To Create Dynamic Data Web Application - Focus On Security and Performance

    • 1 Comments

    This post walks through the steps I've taken to create simple Dynamic Data Web Application. I just loved the development model for DTO [Data Transfer Object] and Input Validation options.

    Summary of steps

    • Step 1 - Download and install ASP.NET Extensions.
    • Step 2 - Create New Dynamic Data Web Application in VS2008
    • Step 3 - Add "LINQ to SQL Classes" file to the project
    • Step 4 - Test the project
    • Step 5 - Create Model Class and add validation rules

    Following are detailed explanations for each step.

  • Step 1 - Download and install ASP.NET Extensions. ASP.NET Extensions can be found here - http://asp.net/downloads/3.5-extensions/. I installed it on my Vista machine that has Visual Studio 2008 installed.
  • Step 2 - Create New Dynamic Data Web Application in VS2008. Open Visual Studio 2008 and choose "Dynamic Data Web Application" template found under Web node. Make sure that the project references System.Web.Extensions assembly version 3.6. If not then remove it and reference the assembly from "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\ASP.NET 3.5 Extensions\System.Web.Extensions.dll".
  • Step 3 - Add "LINQ to SQL Classes" file to the project. Right click on the project and choose "Add"->"New Item..." and then choose "LINQ to SQL Classes" template from "Data" node. In server Explorer expand "Data Connections" node, expand desired database, and then expand "Tables" node. Highlight desired tables and then drag them onto "LINQ to SQL Classes" component [double click file with .dbml extension].
  • Step 4 - Test the project. Right click on default.aspx page and choose "View in Browser". The page should look similar to the picture below. Click on the tables names to see the actual values and master-child view.

     image

  • Step 5 - Create Model Class and add validation rules. Adding validation rules can be accomplished using .Net attributes declaratively or using partial methods. Create new class. Add "using System.Web.DynamicData;" declaration. Delete the default constructor. Add partial class with the name of desired table, say "Item" or/and  "Product".
      • Attribute based input validation. Add attribute to the class, for example to check range for ListPrice field/column and add the following declaration:image
      • Partial method input validation. Add partial method for desired field change [intelliSense really rocks at this part] and then add validation logic:image

    Validation rules propagated to both client [for usability] and server [for security], this is how violation of input validation looks in it default view:

    image

    Heaven.

    Focus on Security

    I can create data driven web pages using GridView and DataSets. The drawback is that validation is not that straightforward. On other hand I can create custom collections and manually data bind it - the code is much nicer and cleaner and validation rules are easy to add but there is the need of writing extra code. In the case of Dynamic Data there is fantastic combination of design time productivity and also clean code where validation rules are applied directly to the model. Less room for mistake to introduce security vulnerability.

    Focus on Performance

    Ready to go templates that are generated with the default Dynamic Data projects already implement AJAX and paging. It reduces dramatically amount of data that round trips over the wire. Large HTML output - including ViewState - is one of the biggest performance vulnerabilities I've noticed recently. AJAX and paging is a great way to overcome this issue.

    My related posts

      Related materials

    • Page 1 of 2 (6 items) 12