martes, 17 de enero de 2012

Script Injection to Server Controls

In this time i want to share with you a very interesting practice to work with about asynchronous functionality and scripting injection over ASP.NET. Although it represents a laborious task when dealing with JavaScript and do not have the Intellisense goodness, it is quite useful for creating custom controls with asynchronous functionality embedded. With this example i want to show you a brief introduction of how custom controls with asynchronous functionaliity are build, one example could be the ajax control toolkit. We need to create a Class Library for the component creation. Name it PasswordTextbox Delete all clases and create a new one and name it the same way you named the proyect PasswordTextbox The class will have the next code in it:


using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Web;

namespace PasswordTextbox
{
    public class PasswordTextbox: TextBox, IScriptControl
    {
        private ScriptManager _scriptManager;

        public string WeakCssClass;
        public string MediumCssClass;
        public string StrongCssClass;

        protected virtual IEnumerable GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("AjaxEnabled.PasswordTextbox",this.ClientID);
            descriptor.AddProperty("weakCssClass", this.WeakCssClass);
            descriptor.AddProperty("mediumCssClass", this.MediumCssClass);
            descriptor.AddProperty("strongCssClass", this.StrongCssClass);

            return new ScriptDescriptor[] {descriptor};

        }

        protected virtual IEnumerable GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            reference.Assembly = "AjaxEnabled";
            reference.Name = "AjaxEnabled.PasswordTextbox.js";

            return new ScriptReference[] { reference };
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (!this.DesignMode)
            {
                //test for the existence of a script manager
                _scriptManager = ScriptManager.GetCurrent(Page);
                if (_scriptManager == null)
                {
                    throw new HttpException("A ScriptManager control must exist in the page.");
                }
                _scriptManager.RegisterScriptControl(this);
            }
            base.OnPreRender(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (!this.DesignMode)
            {
                _scriptManager.RegisterScriptDescriptors(this);
            }
            base.Render(writer);
        }

        IEnumerable IScriptControl.GetScriptDescriptors()
        {
            return GetScriptDescriptors();
        }

        IEnumerable IScriptControl.GetScriptReferences()
        {
            return GetScriptReferences();
        }

    }
}


As you can see, the class inherits from TextBox and implements the IScriptControl interface. The IScriptControl interface implemantation enables you to use asinchronous functionality using this two methods internals at class level for the scripts injection:

1) GetScriptReferences - This methods injects the script reference(in this case "AjaxEnabled.PasswordTextbox.js").
2) GetScriptDescriptors - This method simply adds the scripts to the ScriptManager of the server control.

As you can see we need to create the script referenced, so at the same level of the class, add a .js file called PasswordTextbox.js and add the next code:


/// 

Type.registerNamespace("AjaxEnabled");

//Create constructor
AjaxEnabled.PasswordTextbox= function (element) {
    AjaxEnabled.PasswordTextbox.initializeBase(this, [element]);
    this._weakCssClass = null;
    this._mediumCssClass = null;
    this._strongCssClass = null;
}

//define class
AjaxEnabled.PasswordTextbox.prototype = {

    //initialize the UI control
    initialize: function () {
        AjaxEnabled.PasswordTextbox.callBaseMethod(this, 'initialize');

        this._onKeyupHandler = Function.createDelegate(this, this._onKeyup);
        $addHandlers(this.get_element(), { 'keyup': this._onKeyup }, this);
    },

    //In Microsoft Ajax frameworks theres also a dispose method.
    dispose: function () {
        $clearHandlers(this.get_element());
        AjaxEnabled.PasswordTextbox.callBaseMethod(this, 'dispose');
    },

    //define keystroke event wich will be referenced on the onkeyup HTML control declaration (onkeyup=_onKeyup(this);
    _onKeyup: function (e) {
        //get password text
        var pass = this.get_element().value;
        var strength = this.returnPasswordStrength(pass);
        switch (strength) {
            case 'Weak':
                this.get_element().className = this._weakCssClass;
                break;
            case 'Medium':
                this.get_element().className = this._mediumCssClass;
                break;
            case 'Strong':
                this.get_element().className = this._strongCssClass;
                break;
        }
    },

    //Define properties setters and getters for the control public properties.
    get_weakCssClass: function () {
        return this._weakCssClass;
    },
    set_weakCssClass: function (value) {
        this._weakCssClass = value;
    },
    get_mediumCssClass: function () {
        return this._mediumCssClass;
    },
    set_mediumCssClass: function (value) {
        this._mediumCssClass = value;
    },
    get_strongCssClass: function () {
        return this._strongCssClass;
    },
    set_strongCssClass: function (value) {
        this._strongCssClass = value;
    },

    //This function validates the strength of the password and returns the complexity of it.
    returnPasswordStrength: function (password) {
        var strPass = new String(password.toString());
        if (strPass.length < 5) {
            return "Weak";
        }
        else {
            if (strPass.length < 8) {
                return "Medium";
            }
            else {
                return "Strong";
            }            
        }
    }
}

//Register class as a Sys.Control (The type of control recognized by the Microsoft Ajax library)
AjaxEnabled.PasswordTextbox.registerClass('AjaxEnabled.PasswordTextbox', Sys.UI.Control);

//We notify to the scriptManager that the script has been loaded
if (typeof (Sys) !== 'undefined')
    Sys.Application.notifyScriptLoaded();

This script must exist as an embbedded resource into the solution. TO do this follow these steps:
1) Right click over the PasswordTextbox.js file(Solution Explorer) and in the context menu left click to the properties option.
2) In the build action option, change the property Build Action to Embedded Resource

After this, your component is ready to use. Just compile the component and reference it to a page over a Web site:

<%@ Register assembly="AjaxEnabled" namespace="AjaxEnabled" tagPrefix="ajaxEnabled"%>



I hope this introduction to script injection to server controls liked you. Se you at the next post.
Best Regards!

viernes, 13 de enero de 2012

What's an MCP?

In this first post, i want to share with all the blog followers a reflection in my opinion about, what's an MCP.

An MCP is not just a "Title" i believe is in fact a way of life... why a way of life?, perhaps your asking, well, its a way of life because its more than just write a bunch of lines of code in the best way, or perhaps being great at implementing certain technology. If you thinking so, then your going the wrong way.

What i want to share with all of you is that in my experience, being an MCP or a Microsoft Certified Professional is in fact resumed in one word "Share", share your knowledge with your friends, with your work companions, your boss, its exchange knowledge to help others solve many problems you aware in the day to day. Thats what makes you a really professional, beign professional with your work and compromising yourself with giving a little of you to many others. Think it twice and you'll se that what im telling you its right and lets you learn more about yourself and others. You dont need to have an MCP title, so i invite you to reflex about this and became a real MCP Fighter and learn from everywhere you can, teach and help many others. So thats the reason for me to create this post, to share with many others what i know, to exchange with others its expertise in a constructive way.

Welcome!