Kurser och utbildning av IT-proffs och systemutvecklare

i Sök

Cornerstones utvecklarblogg

Alla Taggar

All Tags » ASP.Net Ajax   (RSS)

  • ASP.NET AJAX 4.0 Preview 5 – Working with Converters and the new CDN

    In this blog post I’m going to show you how you can use the new Converter feature during data binding, to make this post more special I have used the new Microsoft AJAX CDN (Content Delivery Network), so I don’t need to have the AJAX 4.0 script on my server. The example code I use in this post, will use the ASP.NET AJAX DataView and also Microsoft ADO.NET Data Services to retrieve data from the server. My fantasy isn’t so special good, but I decided to make a little “rental” application, where I will use ASP.NET AJAX to simply show a list of cars and the current rental status. The status of a rental car will be sent to the client as a string and can be of the following values, Approved, Not Approved and Pending. The little app I’m building for this post, will show the rental status as different colors for the user.

    image


    Green color will show that the rental of the car is approved, red will indicate not approved and yellow will indicate a pending status. My little database have one simple table, called Rental (lack of fantasy), with three columns, ID, Description and Status. I have used Entity Framework together with ADO.Net Data Source to get the data from the database. Here is the ADO.NET Data Service, I have added a Rental operation to only enable access to the operation to get Rental entities.

    public class RentalWebDataService : DataService<RentalModel.RentalEntities>
    {
        public static void InitializeService(IDataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("Rental", EntitySetRights.AllRead);
            config.SetServiceOperationAccessRule("Rental", ServiceOperationRights.AllRead);
        }
    
        [WebGet]
        public IQueryable<RentalModel.Rental> Rental()
        {
            return this.CurrentDataSource.Rental;
        }
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    To use ASP.NET AJAX 4.0 Preview 5, I have not used my local scripts, instead use the new Microsoft AJAX CDN. The Microsoft CDN service provides caching support for AJAX libraries (including jQuery and ASP.NET AJAX) and are composed of “edge cache” servers, they are strategically placed around the world to make sure your application will use the nearest server to get the ASP.NET AJAX scripts, isn’t that cool?! The service is free and both for commercial and non-commercial purpose. To get a JavaScript from the Microsoft CDN, you can simply use the <script> tag to include the script from ”http://ajax.microsoft.com/ajax”. Microsoft CND will use sub folders to versioning the different kind of scripts. The ASP.NET AJAX 4.0 Preview 5.0 script can be found under the /0909/ folder (the name of the folder represents the year and month when the ASP.NET AJAX was released). You can find the JavaScript and URLs here: http://www.asp.net/ajax/cdn/

    Note: ScriptManger can automatically request JavaScript files form the Microsoft CDN if the EnableCdn property of the ScriptManager is set to true.


    I have used the following code to include the ASP.NET AJAX 4.0 Preview 5.0 script in my demo, to make sure I can use Templates, and ADO.NET DataServices:

    <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjaxTemplates.js" type="text/javascript"></script> <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjaxAdoNet.js" type="text/javascript"></script>
    <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjaxDataContext.js" type="text/javascript"></script>
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    To use the ADO.NET Data Service (RentalWebDataSerivce) on the client-side, the ASP.NET AJAX $create shortcut can be used to create a ADO.Net DataContext object, the DataContex is the proxy class to access the ADO.Net Data Service:

    var RentalService = {};
    
    RentalService.dataContext = $create(Sys.Data.AdoNetDataContext,
                                             {
                                                 serviceUri: "RentalWebDataService.svc",
                                                 mergeOption: Sys.Data.MergeOption.appendOnly
                                             });
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    The following is the template I have used to list the cars:

     <table sys:attach="dataview"
            class="sys-template"
            dataview:dataprovider="{{ RentalService.dataContext }}"
            dataview:fetchoperation="Rental"
            dataview:autofetch="true">
    
            <tr sys:if="$index==0">
                <td>Booking No</td>
                <td>Description</td>
            </tr>
            
             <tr sys:style-background-color="{binding Status, convert=convertStatusToColor, ColorType=Name}">
                 <td>{{ ID }}</td>
                 <td>{{ Description }}</td>
             </tr>
    </table>
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    Yes, I know, I use a table instead of a DIV, shame on me..

    To create a template the class=”sys-template” must be applied to the root element of the template, the sys:attached=”dataview” will indicate that I will use the ASP.NET AJAX 4.0 DataView features together with the template. To make sure the DataView will get its data from the RentalWebDataService, the dataview:dataprovider attribute is used and its value is set to the RentalService.dataContext object, the DataView’s autofecth property is also set to true, to automatically fetch data. The fetchoperation property will specify which operation of the RentalWebDataServices should be used when the DataView fetches the data.

    There are two ways to bind data within a template, for example the short {{ field }} expression or the {binding field} expression. As you can see I have used both expressions in the template, one for the background-color style (to bind a value to a specific style attribute, the sys:style-<style> attribute is used). The {{ ID }} and {{ Description }} shortcut will make sure to get the data from the Rental’s (The entity returned from the Rental operation of the RentalWebDataService ) ID and Description property. Take a look at the binding expression used for the <tr> background-color style:

    <tr sys:style-background-color="{binding Status, convert=convertStatusToColor, ColorType=Name}">
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }


    There is now an option to specify a Converter, a method which will take the bounded value and pass it as an argument to the specified method and do a conversion and return a new whole value. The Status property in my case returns a string with different kind of status, Approved, NotApproved and Pending. What I want to do, is to convert those values into different colors as I mention earlier in my post. To do that I have used the new Converter feature. To set up a converter is easy just use the Sys.Binding.converters property and assign a method to it with two arguments, the value to convert and a binding argument (holds information about the binding).

    Sys.Binding.converters.convertStatusToColor = function(status, binding)
    {
         //do something then return the converted value
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    One great thing with the converter, is the possibility to use expandos, for example in my code I have added a ColorType expando to specify if the color that returned from the converter should be a name or not. The binding argument of the converter method can be used to get the expando, for example:

    "{binding Status, convert=convertStatusToColor, ColorType=Name}"
    
    
    Sys.Binding.converters.convertStatusToColor = function(status, binding)
    {
        if( binding.ColorName == 'Name')
              //....
         //do something then return the converted value
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    I have created the ugliest converter method ever made, here it is:

    Sys.Binding.converters.convertStatusToColor = function(status, binding)
    {
           if (binding.ColorType == 'Name')
          {
                 if (status == 'Approved')
                        return 'green';
                    else if (status == 'NotApproved')
                        return 'red';
                    else if (status == 'Pending')
                        return 'yellow';
                    else
                        return 'white';
            }
            else
           {
                 if (status == "Approved")
                     return '#00ff00';
                 else if (status == "NotApproved")
                     return '#ff0000';
                 else if (status == 'Pending')
                     return '#ffff00';
                 else
                     return '#ffffff';
            }
    }
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    Well, it’s a simple method to convert the incoming string, and return a color for the <tr>’s background-color. Here is the whole client-side code:

    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjax.js" type="text/javascript"></script> 
        <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjaxTemplates.js" type="text/javascript"></script>
        <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjaxAdoNet.js" type="text/javascript"></script>
        <script src="http://ajax.microsoft.com/ajax/beta/0909/MicrosoftAjaxDataContext.js" type="text/javascript"></script>
    
    
        <script type="text/javascript">
    
            var RentalService = {};
    
            RentalService.dataContext = $create(Sys.Data.AdoNetDataContext,
                                             {
                                                 serviceUri: "RentalWebDataService.svc",
                                                 mergeOption: Sys.Data.MergeOption.appendOnly
                                             });
    
    
            Sys.Binding.converters.convertStatusToColor = function(status, binding) {
    
                if (binding.ColorType == 'Name') {
    
                    if (status == 'Approved')
                        return 'green';
                    else if (status == 'NotApproved')
                        return 'red';
                    else if (status == 'Pending')
                        return 'yellow';
                    else
                        return 'white';
                }
                else {
                    if (status == "Approved")
                        return '#00ff00';
                    else if (status == "NotApproved")
                        return '#ff0000';
                    else if (status == 'Pending')
                        return '#ffff00';
                    else
                        return '#ffffff';
                }
            }
    
        </script>
        
        <style type="text/css">
            .sys-template { display:none; }
        </style>
    
    </head>
    <body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView">
        
        <table sys:attach="dataview"
            class="sys-template"
            dataview:dataprovider="{{ RentalService.dataContext }}"
            dataview:fetchoperation="Rental"
            dataview:autofetch="true">
    
            <tr sys:if="$index==0">
                <td>Booking No</td>
                <td>Description</td>
            </tr>
            
             <tr sys:style-background-color="{binding Status, convert=convertStatusToColor, ColorType=Name}">
                 <td>{{ ID }}</td>
                 <td>{{ Description }}</td>
             </tr>
        </table>
        
    </body>
    </html>
    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    Summary

    In this blog post you have seen how to data bind and use the DataView to do client-side binding to a ADO.NET Data Service, you have also got introduced to the Microsoft AJAX NDC, if you want to get more information about the NDC, check out Scott Guthrie's blog: http://weblogs.asp.net/scottgu/archive/2009/09/15/announcing-the-microsoft-ajax-cdn.aspx, you have also seen the new Preview 5 converter feature.

    To find more information about ASP.NET AJAX 4.0 Preview 5.0, you can check out my two earlier posts:

    http://weblogs.asp.net/fredriknormen/archive/2009/09/11/asp-net-ajax-4-0-preview-5-available.aspx

    http://weblogs.asp.net/fredriknormen/archive/2009/09/11/keep-the-first-empty-item-in-a-listbox-when-using-asp-net-ajax-4-0-preview-5-and-observer.aspx

    Jim, Dave and Bertrand Le Roy’s posts on Preview 5:
    http://weblogs.asp.net/jimwang/archive/2009/09/11/asp-net-ajax-preview-5-and-updatepanel.aspx

    http://weblogs.asp.net/infinitiesloop/archive/2009/09/10/microsoft-ajax-4-preview-5-the-dataview-control.aspx

    http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx

     

    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
  • Expression Studio 2.0 är här!

    Robert Folkesson på Microsoft skriver på sin blogg att Expression Studio 2.0 är här. http://blogs.msdn.com/robf/archive/2008/05/04/expression-studio-2-har-sl-ppts.aspx I dagsläget har verktygen stöd för Silverlight 1.0 Läs mer...
  • My Tips &amp; Tricks Slide from the MSDN Live

    I hold a session at MSDN Live in Sweden for some weeks ago. The slides are now availbable.

    The tips in my slides are a collection of what I have seen several of people don't think about when they use ASP.Net Ajax, or have used the technology in a wrong way etc. It's gathered from different communities. I have also some hidden slides for the people who want to learn more about how to do Object-Oriented Programming with Inheritance etc by using the ASP.Net AJAX Library.

    You can download the slide from here. (The language I used in the slide is English)



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • The book ASP.Net AJAX in Action, what a book :)

    If you want to learn ASP.Net AJAX and also want to have a good deep dive into it, then I will recommend a very good book ASP.Net AJAX in Action. It will give you not all the basic you need to know, it will also make you a good client-side script writer, were you will learn how to use all shortcut you can when using the client-side ASP.Net AJAX Library.

    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • Use Interfaces with java-script by using ASP.Net AJAX

    I will probably be at the TechED this year also (Barcelona), so I hope to see some of you there. I think this year’s TechED will ROCK! At the moment I’m working on some Silverlight screen caps, at the moment they are only in Swedish. I have tried VS 2008 Beta 2 for a while and it have never crashed for me yet, so if some of you wonder if it’s stable. Well I think so. I did have some problems with my old VS 2005 on the same machine (Yes, I know. I should have used Virtual PC, but I wanted to try to see how beta 2 and VS 2005 would work on the same machine). Now to some AJAX stuff.

    In this post I’m going to show you how you can use Interfaces in Java-script with ASP.Net AJAX Client Library. As you may know java-script don’t support interfaces, but ASP.Net AJAX made it possible ;)

    The following code is n interface:

    Nsquared2.ICustomer = function()
    {
        throw Error.notImplemented();
    }

    Nsquared2.ICustomer.prototype =
    {
        get_firstName: function()
        {
            throw Error.notImplemented();
        },
        get_lastName: function()
        {
            throw Error.notImplemented();
        }
    }

    Nsquared2.ICustomer.registerInterface('Nsquared2.ICustomer');

    As you can in the code above, we actually define an Interface in a similar way as we create a Class with the ASP.Net AJAX Client Library. The only different here is the registerInterface method that will register our interface to be used as an interface. To make sure no one should use the ICustomer as a class, we throw a notImplemeted exception. The ASP.Net AJAX Client Library has an Error object with different kind of pre-defined exception that we can use; the notImplemented is one of them.

    To use the interface we simply make sure our class implements the method in the interface, in this case the get_firstName and get_lastName:

    Nsquared2.Customer.prototype =
    {
            ...
            get_firstName: function()
            {
                //Implement the method body here
            },
            get_lastName: function()
            {
                //Implement the method body here
           }

    }

    Note: You can read about how to create a class in my post Create a "class" (type) in Java-Script by using the ASP.Net Ajax Library

    When our class in created we pass the interface to the registerClass method of our class to make sure it will use the interface:

    Nsquared2.Customer.registerClass('Nsquared2.Customer', null, 'Nsquared2.ICustomer');

    Note: The registerClass method is explained in my previous posts about creating classes.

    Create a "class" (type) in Java-Script by using the ASP.Net Ajax Library

    Create a base and sub class and use inheritence with ASP.Net AJAX and java-script



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • Create a base and sub class and use inheritence with ASP.Net AJAX and java-script

    For some weeks ago I wrote a post about how to create a class with the ASP.Net AJAX Client Library. In this post I will talk more about how to work with Object-Orientation on the client-side with Java-script, so if you have read my first post about the ASP.Net AJAX Client Library you will get the basics about creating classes so I will not repeat it here, instead I will show you how you can create a base class and sub class and use inheritance.

    The following example is a simple base class that represents a Shape:

    Type.registerNamespace(’Nsquared2.ASPAJAX.Samples.Shape);

    Nsquared2.ASPAJAX.Samples.Shape = function(name, color)
    {
       this._name = name;
       this._color = color;
    }

    Nsquared2.ASPAJAX.Samples.Shape.prototype =
    {
       get_Name: function()
       {
           return this._name;
       },
       get_Color : function()
       {
           return this._color;
       }
    }

    Nsquared2.ASPAJAX.Samples.Shape.registerClass(’ Nsquared2.ASPAJAX.Samples.Shape’);

    The following code is a class that represents a Square which “is a” shape:

    Nsquared2.ASPAJAX.Samples.Square = function(name, color, x, y)
    {
        Nsquared2.ASPAJAX.Samples.Square.initializeBase(this, [title, color]);
        this._x = x;
        this._y = y;
    }

    Nsquared2.ASPAJAX.Samples.Square.prototype =
    {
         get_x: function()
         {
             return this._x;
         }
         get_y: function()
         {
             return this._y;
         }
    }

    Nsquared2.ASPAJAX.Samples.Square.registerClass(
    ‘Nsquared2.ASPAJAX.Samples.Square’,’Nsquared2.ASPAJAX.Samples.Shape);

    var square = new Nsquared2.ASPAJAX.Samples.Square(“My Square”, “red”, 10, 20);

    alert(square.get_Color);

    When we create a sub class we need to make a call to the initializeBase method from our constructor. If we don’t do that, we can’t access the base class’s members. When the constructor make a call to the initializeBase, it will pass itself (using “this”) and along with the argument that should be passed to the base constructor.

    The registerClass method will take the class it should create and also the base class it should extend as an argument. The registerClass can take three possible parameters, the class to create, the base class to extend and the interface that should be used.

    This is all we need to create a base and sub class and use inheritance. If we want to make a call to a base class method form the sub class, we can use the callBaseMethod. The following code will override the get_Name property of the base class:

    Nsquared2.ASPAJAX.Samples.Square.prototype =
    {
         …
         get_name : function()
         {
              return “Square’s Name: “ + Nsquared2.ASPAJAX.Samples.Shape.classBaseMethod(this, “get_name”));
         }
    }

    We can also create interfaces and create a class that implements an interface, I will write a separate post about that in a near future ;)



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • Create a &quot;class&quot; (type) in Java-Script by using the ASP.Net Ajax Library

    When you are using the ASP.Net Ajax Extension and add a ScriptManger to your page, you can easy use the ASP.NET Ajax Library to make it easier to handle client-side script (Java-script), you can easy with the AJAX Library create namespace and “classes” (types), use Object-oriented programming) OOP. As you may know java-script doesn’t have build-in support for most OOP concepts.  Microsoft has tried to reflect the client-side java-script in a similar way of creating classes etc as in C#. This will help developers to have a similar way of writing client-side script as they write server-side code (minimize the differences). This post will take a look at how you can create a namespace to categorize classes and also how to create a class with the AJAX Library with client-side script. I will later in other posts go more into how you can sort of do inheritance and use interfaces etc, things that don’t exists in client-side script, but what the ASP.Net Ajax library make possible.

    Here is an example of a Customer class on the client.side:

    Type.registerNamespace(’Nsquared2.ASPAJAX.Samples.Customer’);

    Nsquared2.ASPAJAX.Samples.Customer = function(firstName, lastName, address)
    {
       this._firstName = firstName;
       this._lastName = lastName;
       this._address = address;
    }

    Nsquared2.ASPAJAX.Samples.Customer.prototype =
    {
       get_firstName: function()
       {
           return this._fistName;
       },
       get_lastName : function()
       {
           return this._lastName;
       }
    }

    Nsquared2.ASPAJAX.Samples.Customer.registerClass(’ Nsquared2.ASPAJAX.Samples.Customer’);

    var myCustomer = new Nsquared2.ASPAJAX.Samples.Customer(’Fredrik’, ’Normén’,’My address’);
    alert(myCustomer.get_firstName);

    By using the registerNamespace method of the Type class, you can create namespace and register the use of it. The registerNamespace method will create four objects, Nsquared2, ASPAJAX, Samples and Customer. You can by using the Nsqaured2 object get access to the ASPAJAX object etc. The objects can have some metadata, which for example can be used to identify them as namespaces. It can also use them to hold other objects that are added to the namespace.

    To define a class we simply assign a method:

    Nsquared2.ASPAJAX.Samples.Customer = function(firstName, lastName, address)  { }

    The Nsquared2.ASPAJAX.Samples.Customer will now work as a “class” (even if classes don’t exist in java-script, ASP.Net Ajax Library will provide us a way of creating a “class”).  As you may know all arguments in java-script is kind of optional, so you don’t need to use all arguments when you instantiate the Customer class.  The assigned function will be used as the constructor for the class, and in the example it takes three arguments that will assigns them to local variable by using “this”. The “this” keyword will make sure the variables, _firstName, _lastName and _address will be in a local scope mode and find in a local scope and not in global scope.

    Nsquared2.ASPAJAX.Samples.Customer = function(firstName, lastName, address)
    {
       this._firstName = firstName;
       this._lastName = lastName;
       this._address = address;
    }

    To add properties and methods to the Customer “class”, we can use the prototype. The prototype of the base type in Java-script has been modified to add type-system support. The following code will add two get method to the Customer’s prototype that will work as properties:

    Nsquared2.ASPAJAX.Samples.Customer.prototype =
    {
     get_firstName: function()
     {
        return this._fistName;
     },
     get_lastName : function()
     {
        return this._lastName;
     }
    }

    To make sure we can make a call to the get_firstName and get_lastname functions, we need to register the class. This is done by calling the registerClass method:

    Nsquared2.ASPAJAX.Samples.Customer.registerClass(’ Nsquared2.ASPAJAX.Samples.Customer’);

    The registerClass method takes three arguments, name of the type, base type to extend and the interface a “class” implements. I will write more about the two last arguments in a later post.

    When this is done, we can now create an instance of our “class” and use it:

    var myCustomer = new Nsquared2.ASPAJAX.Samples.Customer(’John’, ’Doe’,’My address’);
    alert(myCustomer.get_firstName);

    The code above will create an instance of the Customer ”class” and fill the local variables _firstName, _lastName and address with a value passed as arguments, and an alert will be used to display the value of the firstName property.



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • MSDN TV about Ajax for Swedish developers

    I have recently got home from the MVP Summit in Seattle/Redmond. It was a good way to meet other MVPs and also the product teams. During my time in Seattle, Microsoft in Sweden has published 3 of my movies about ASP.Net Ajax (7 more will come). So for my Swedish readers that maybe are interested in ASP.Net Ajax, take a look at the following site:

    http://www.microsoft.com/sverige/msdn/msdntv/



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • Answers to some common questions regarding ASP.Net Ajax

    I got some common questions lately regarding ASP.Net Ajax and maybe some more are interested in the answers, so I will publish some of them in this post.

     

    When I use ASP.Net Ajax and do an async. postback, the Back button will not work, how to make it work?

     

    Take a look at Nikhil Kothari’s UpdateHistory control, a really cool feature that will probably be available in the “Orcas” release.

     

    How can I update an UpdatePanel programmatically?

     

    You can use the Update method of the UpdatePanel on the server-side. Make sure to set the UpdateMode of the UpdatePanel to Conditional to get it work.

     

    <asp:UpdatePanel UpdateMode="Conditional" ID="UpdatePanel1"...>

     

    UpdatePanel1.Update()

     

    You can also use triggers that will make sure the UpdatePanel listen to a control’s event and will do an update if the event if fired and caused by a postback. Example:

     

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">

             <ContentTemplate>

                   ...

             </ContentTemplate>

             <Triggers>

                    <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />

              </Triggers>

    </asp:UpdatePanel>

     

    <asp:Button ID="Button1" runat="server" Text="Button" />

     

    I have created a Web user control and have a button, when I press on that button I register a script with Page.ClientScript.RegisterStartupScript and it works. But when I put the control into my UpdatePanel the client-side script will not work, any idea?

     

    You need to use the ScriptManager to register the script block, because the scripts registered with the Page object will not be sent back to the client after a partial update. You can for example use the ScriptManager.GetCurrent method to get the instance of the ScriptManager added to your page, and then use its RegisterClientScriptBlock method, for example:

     

    VB.Net

     

    Dim current As ScriptManager = ScriptManager.GetCurrent(Me.Page)

    current.RegisterClientScriptBlock(Me.Page, Me.GetType(), "key", "your script", True)

     

    C#

     

    ScriptManager current = ScriptManager.GetCurrent(this.Page);

    current.RegisterClientScriptBlock(this.Page, this.GetType(), "key2, "your script", true);

     

     



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • Solution for the UpdateProgress control and UpdatePanel with Triggers

    When you use the UpdatePanel control you probably also want to display some kind of progress bar to the user so they can see when the async. postback starts and when it’s done, at least something that indicate that some work are being done and they need to wait until it’s done. This can be done by using the UpdateProgress control shipped with ASP.Net Ajax 1.0 Extension. If you use the UpdatePanel control and specify an AsyncPostBackTrigger and also associate the UpdateProgress to an UpdaetPanel, the UpdateProgress control will not be displayed. I assume some of you have notice that. For example:

     

    <asp:Button ID="Button1" .../>

    <asp:UpdatePanel ID="UpdatePanel1" ...>
       <ContentTemplate>

          ...
       </ContentTemplate>
       <Triggers>
          <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click"/>

       </Triggers>
    </asp:UpdatePanel>

    <asp:UpdateProgress AssociatedUpdatePanelID="UpdatePanel1" ...>
       <ProgressTemplate>
           Please wait, update in progress
       </ProgressTemplate>
    </asp:UpdateProgress>

     

    The code above will not display the UpdateProgress when we press the Button1 button, even if we have specified an AsyncPostBackTrigger. In that case, the UpdateProgress control cannot determine automatically that an asynchronous postback has been triggered. So we need to use client-side script to display and hide the UpdateProgress control, to do that we use the PageRequestManager and hook up to the InitalizeRequest and EndRequest event. Here is an example:

     

    <script language="javascript" type="text/javascript">

     

       var prm = Sys.WebForms.PageRequestManager.getInstance();

     

       prm.add_initializeRequest(InitializeRequest);

       prm.add_endRequest(EndRequest);

     

       function InitializeRequest(sender, args)

       {

       }

     

       function EndRequest(sender, args)

       {

       }

    </script>

     

    To hook up to the events we first need to get the Instance of the PageRequestManager, this can be done by using the Sys.WebForms.PageRequestManager.getInstance method:

     

    var prm = Sys.WebForms.PageRequestManager.getInstance();

     

    Next we hook up to the InitializeRequest and EndRequest event. This can be done by using the add_initializeRequest and add_endRequest methods of the PageRequestManager. To hook up to an event, we pass the name of the client-side method that should be executed when the event is trigged:

     

    prm.add_initializeRequest(InitializeRequest);

    prm.add_endRequest(EndRequest);

     

    function InitializeRequest(sender, args)

    {

    }

     

    function EndRequest(sender, args)

    {

    }

     

    The method we specify uses two arguments, the sender and the args (event args), very similar to the EventHandler delegate in .Net. The InitializeRequest event will be trigged when the async. call to the server starts (when the request are initialized) and the EndRequest will be trigged when the request ended (when we got the results from the server after an async. call).

     

    When we have hooked up to the events we need to ad some code to the Inistalize- and EndRequest methods. First we make sure to cancel the async. postback if there are anyone in progress. To cancel an async. postback we first want to see if an async. postback is in progress, this can be done by using the PageRequestManager’s get_isInAsuncPostBack method, and to cancel the async. postback we make a call to the set_cancel method of the “args” argument passed to the InitialzeRequest method and pass the value true:

     

    if (prm.get_isInAsyncPostBack())

        args.set_cancel(true);  

     

    The next step to do in the InitialzeRequest is to see if the Button1 is the element that did the postback, and if that is the case, we get the element of the UpdateProgress control and display it. To check if Button1 was the element that did the postback we can use the get_PostBackElement method of the “args” arguments to get the element, and use its Id property to see if it has the same id as our button that did the postback. If it has the same id, we use the document.getElementById (when we use the ASP.Net Ajax, we can use the short cut $get that is the same as document.getElementById) to get the UpdateProgress element and display it by using the style.display property:

     

    postBackElement = args.get_postBackElement();

     

    if (postBackElement.id == 'Button1')

       $get('UpdateProgress1').style.display = 'block';

     

    Now we are done with the InitializeRequest method and the method would look like this:

     

    var postBackElement;

     

    function InitializeRequest(sender, args)

    {

       if (prm.get_isInAsyncPostBack())

          args.set_cancel(true);

     

       postBackElement = args.get_postBackElement();

     

       if (postBackElement.id == 'Button1')

          $get('UpdateProgress1').style.display = 'block';

    }

     

    Now when we have displayed the UpdateProgress control when an async. postback begins, we also need to hide it when the EndRequest is ended.

     

    To hide the UpdateProgress control, we need to get its element and then use the style.display property to hide the element. We will also make sure to only hide the UpdateProgress if the Button1 did the async. postback, we can do that by using the postBackElement variable that is already set to an element in the InitializeRequest method:

     

    if (postBackElement.id == 'Button1')

       $get('UpdateProgress1').style.display = 'none';

     

    As you can see in the code above, we pass the id of the UpdateProgress control to the $get method to get the element of the UpdateProgress control. To hide the UpdateProgress element, we set its style.display property to ‘none’. Here is the whole EndRequest method:

     

    function EndRequest(sender, args)

    {

        if (postBackElement.id == 'Button1')

           $get('UpdateProgress1').style.display = 'none';

    }

     

    Here is the whole client-side script (Make sure to add it after the ScriptManger control, if you don’t do that you will get an exception that the Sys is not defined):

     

    <asp:ScriptManager ID="ScriptManager1" runat="server" />

     

    <script language="javascript" type="text/javascript">

     

       var prm = Sys.WebForms.PageRequestManager.getInstance();

     

       prm.add_initializeRequest(InitializeRequest);

       prm.add_endRequest(EndRequest);

     

       var postBackElement;

     

       function InitializeRequest(sender, args)

       {

          if (prm.get_isInAsyncPostBack())

             args.set_cancel(true);

     

          postBackElement = args.get_postBackElement();

     

          if (postBackElement.id == 'Button1')

             $get('UpdateProgress1').style.display = 'block';

       }

     

       function EndRequest(sender, args)

       {

           if (postBackElement.id == 'Button1')

              $get('UpdateProgress1').style.display = 'none';

       }

     

    </script>



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • The UpdateProgress control and display it in the beginRequest event.

    David Barkol sent me a good feedback about the way I display the UpdateProgress control in my previous post. If you take a look at the code in my previous post you can see that I used the initializeRequest to display the UpdateProgress control. I could instead as David mentioned, use the beginRequest to display it. For example like this:

     

    var prm = Sys.WebForms.PageRequestManager.getInstance();

     

    prm.add_initializeRequest(InitializeRequest);

    prm.add_beginRequest(BeginRequest);

    prm.add_endRequest(EndRequest);

     

    var postBackElement;

     

    function InitializeRequest(sender, args)

    {

          if (prm.get_isInAsyncPostBack())

                args.set_cancel(true);

    }

     

    function BeginRequest(sender, args)

    {

          postBackElement = args.get_postBackElement();

     

           if (postBackElement.id == 'Button1')

                  $get('UpdateProgress1').style.display = 'block';

     }

     

     function EndRequest(sender, args)

     {

            if (postBackElement.id == 'Button1')

                  $get('UpdateProgress1').style.display = 'none';

     }

     

    One reason I used the InitializeRequest was to indicate users that an async. postback are going to take place and in the earliest stage as possible. But I agree; it’s more elegant to display the UpdateProgress in the BeginRequest based on its name and reason why it exists. David, made a diagram over the life cycle of an async. postaback, you can find it here http://weblogs.asp.net/davidbarkol/archive/2007/03/25/asp-net-ajax-client-side-event-viewer.aspx.



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • FileUpload control will not work in ASP.Net Ajax during async postback

    As many of you have notice the FileUpload control will not work in an UpdatePanel during an async postback. This is because of security reasons; the async postback is executed on the client-side. Think what will happen if it would be possible for client-side script to access the file system. You can read more about this on Eilon Lipton’s blog (the man behing the UpdatePanel).

    Computers Blogs - Blog Top Sites Bloggtoppen.se


    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • More ASP.Net Ajax movies on MSDN

    For my Swedish readers, Microsoft have published two more ASP.Net Ajax movies made by me on the MSDN Web site: http://www.microsoft.com/sverige/msdn/msdntv/

    This time the movies are about the timer control and exception handling in ASP.Net Ajax.



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se
  • When to use the ScriptManager or Page.CientScript to register client-side script.

    I notice that some people don’t really know what methods they should use to register client-side script if they use partial update. There are two ways of doing it if ASP.Net Ajax is used, one with the Page object and one with the ScriptManager. I will in this post write when you can use the different ways of registering client-side script.

    If you want to register a script from server-side code and the script is not changed dynamically based on some logic and should not be executed directly after an async. postback, you can do it from your Page object. If you have a custom control that should register a script and you will always display the control, and the script should not be changed based on some logic between postback, you can use the Register method of the Page object (Use the ClientScript property of the Page object to get access to them.). If you have your control inside of an UpdatePanel, and need to register the script during an async. postback and the script will be changed based on some logic, then you need to use the ScriptManager's Register methods. But if the control is inside of an UpdatePanel from the start and the client-side script should always be the same, you can use the register methods of the Page object (as long as you should not register a client-side script that need to be executed after a postback).

    Assume you have the following Page:

    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <div>
                <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                    <ContentTemplate>
                        <uc1:WebUserControl ID="WebUserControl1" runat="server" />
                    </ContentTemplate>
                </asp:UpdatePanel>
            </div>
        </form>
    </body>

    There is a User control inside of the UpdatePanel, the User Control have a TextBox with the Id TextBox1 and a Button that will do a postback. The Page_Load of the User control have the following code:

    protected void Page_Load(object sender, EventArgs e)
    {
       ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "myKey", "alert('" + TextBox1.ClientID + "');", true);

       Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "myKey2", "alert('" + TextBox1.ClientID + "');", true);
    }

    When the page is first loaded, two alerts will be displayed, one register by the ScriptManager and one register with the Page object. If we press the button located in the User Control, an async. postback will take place and only the script Registered by the ScriptManager will be executed, but the script for register with the Page object still exists on the page but will not be executed because it's not part of the partial update.

    If you set the Visible property of the User control to false, the two registered script will still be executed because they are located in teh Page_Load method of the User control. But if you move the code to the CreateChildControl of the User Control, they will not be registered until the control is visible. If you have another control inside of the UpdatePanel that should display the User control (you add the control dynamically), only the script registered with the ScriptManager will be executed and the script register by using the Page object will not be added.

    So if you want a script to be registered for a control located in the UpdatePanel, and the Script should always be updated, then use the ScriptManager. If you add a control dynamically during an async. postback, you also need to use the ScriptManager. If you don't add a control dynamically, you can register static scripts in the Page_Load of the control by using the Page object, but if the script code need changes during an async. postback, you should use the ScriptManager.



    Computers Blogs - Blog Top Sites
    Bloggtoppen.se

Den här bloggen

Syndication