Thursday, November 10, 2011

Convert XmlText to HtmlText

I have been using Xml streams for quite some time. When I use them in an ASP.Net page, using SOAP or Ajax calls, I sometimes want to see what I send and what I recieve from the server. Showing them on the page was always a bit of tweak. This ample code demonstrates a very simple tweek. It provides a label that can show the xml Text (as its content or Text property) on the page, by rendering the simpel characters.
When the control is compiled I can use it as one of the two ways:

<panahyAjax:XmlLabel runat="server" ID="xmlLabel">
<this>
 
<is just="one">sample</is>
</this>
</panahyAjax:XmlLabel>

Or

XmlLabel label = new XmlLabel();
var file = File.OpenText("Sample.xml");
label.Text = file.ReadToEnd();

And the code is as folllows:

public class XmlLabel : Label
{
 public static string ConvertXmlTextToHtmlText(string inputText)
 {
  // Replace all start and end tags.
  string startPattern = @"<([^>]+)>";
  var regEx = new Regex(startPattern);
  string outputText = regEx.Replace(inputText, "&lt;<b>$1&gt;</b>");
  outputText = outputText.Replace(
" ", "&nbsp;");
  outputText = outputText.Replace(
"\r\n", "<br />");
  return outputText;
 }

 protected override void RenderContents(HtmlTextWriter output)
 {
  string xmlText = XmlLabel.ConvertXmlTextToHtmlText(Text);
  output.Write(xmlText);
 }
}

Using RenderControl method to generate Html


This article demonstrates how to generate perfect HTML using the RenderControl method of server controls. The Html code is generated without makeing any server-side state or view state.
/// <summary>
/// This method demonstrates how to show Html output of a Server Control
/// </summary>
private void ShowHtml()
{
  // Create the in-memory objects that will catch the rendered output.
  StringWriter writer = new StringWriter();
  HtmlTextWriter output = new HtmlTextWriter(writer);

  // Render the control to an in-memory string.
  var control = new HyperLink();
  control.NavigateUrl =
@"http:\\asghar.panahy.com";
  control.Text =
"Asghar Panahy";
  control.Target =
"_blank";
  control.ToolTip =
"Demostration";

  control.RenderControl(output);

  // Display the HTML (and encode it properly so that
  // it appears as text in the browser).
  lblHtml.Text = "The HTML for LinkWebControl1 is<br /><blockquote>"
               + Server.HtmlEncode(writer.ToString()) +
"</blockquote>";
}

The output of this codewill be reading what you would ecpect in the Html code behind.
Notice that skipping the Server.HtmlEncode call will put the generated html as a link into the page.

Tuesday, November 8, 2011

Encapsulating an AJAX client control into a custom server control (Part 3)

The previous article was a step forward but it is still far from reusing as a server side control. What we will do in this part will make us possible to have a custom textbox control that makes al it takes to have this client-side functionality and we will be able to drag the ASP.NET control into our page.
To start with, we need a new server-side control library project that will compile as a dll and contains the server side code and embeds the client-side script. This project will have two files in it: the PassTextBox.cs which deals with the server-side TextBox and inherits from TextBox and implements the IScriptControl which makes it possible to embed the script code.
Notice in the code that the class needs to register the script with the ScriptManager which is accessible through its static method GetCurrent(Page). This is done in OnPreRender method.
In the previous article we had the css class names inside the javascript. In this example we will assign them through the controls properties. The GetScriptDescriptor method allows us to prototype our class where we define these properties.

namespace Panahy.Ajax
{
 
public class PassTextBox : TextBox, IScriptControl
  {
private ScriptManager sMgr;
public string WeakCssClass;
public string MediumCssClass;
public string StrongCssClass;
protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
 
ScriptControlDescriptor descriptor =
   
new ScriptControlDescriptor("Panahy.Ajax.PassTextBox", this.ClientID);

  descriptor.AddProperty(
"weakCssClass", this.WeakCssClass);
  descriptor.AddProperty(
"mediumCssClass", this.MediumCssClass);
  descriptor.AddProperty(
"strongCssClass", this.StrongCssClass);
  return new ScriptDescriptor[] { descriptor };
}

protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
 
ScriptReference reference = new ScriptReference();

  reference.Assembly =
"Panahy.Ajax";
  reference.Name =
"Panahy.Ajax.PassTextBox.js";
 
return new ScriptReference[] { reference };
}

protected override void OnPreRender(EventArgs e)
{
 
if (!this.DesignMode)
  {
   
//test for the existence of a ScriptManager
   
sMgr = ScriptManager.GetCurrent(Page);

   
if (sMgr == null)
      
throw new HttpException("A ScriptManager control must exist on the page.");
    sMgr.RegisterScriptControl(this);
  }
 
base.OnPreRender(e);
}

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

IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
 
return GetScriptReferences();
}

IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
 
return GetScriptDescriptors();
}
}
}
The javascript file remains as before.
Now we can reuse the control in any project that refers to the dll.

<%@ Register Assembly="Panahy.Ajax" Namespace="Panahy.Ajax" TagPrefix="panahyAjax" %>

<panahyAjax:PassTextBox ID="textbox1" runat="server" width="200"
   
TextMode="Password" WeakCssClass="weak" MediumCssClass="medium"
    StrongCssClass
="strong"></panahyAjax:PassTextBox>



Although this sample can be handy to use as a template for other server controls, the introduced functionality could be done by creating an AJAX Behavior for client controls, which is the topic for the next article.

Implementing Custom Classes for Microsoft AJAX Library (Part 2)

The previous article is demonstrates the use of custom class but it makes some assumption which is not best practice for developping pages.
In this article I will try to make this one step forward by taking the class names (that were hard coded in the javascript) out of the script and assign them in the page. I will also provide a initialization to assign the same functionality to any page element.
We start with the construction and pass the element that is using the class:

Panahy.Ajax.PassTextBox = function(element) {
    Panahy.Ajax.PassTextBox.initializeBase(
this, [element]);

    // initialize internal variables
   
this._weakCssClass = null;
    this._mediumCssClass = null;
    this._strongCssClass = null;
}
Next, I call the passwordStrengthClass method in a new event handler called _onKeyup which I will apply the css class to the element using get_element():

//define key press event
_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;
    }
},
Now, I need to tell the AJAX Library to assign the _onKeyup method to keyup event of the element. To do this, I create a delegate and add the handler as follows:

//initialize the UI control
initialize: function() {
   Panahy.Ajax.PassTextBox.callBaseMethod(
this, 'initialize');

  
this._onKeyupHandler = Function.createDelegate(this, this._onKeyup);
   $addHandlers(
this.get_element(), {'keyup' : this._onKeyup}, this);
},
By doing this, I have to remove the reference when cleaning up the things in the dispose method:

dispose: function() {
    $clearHandlers(
this.get_element());
    Panahy.Ajax.PassTextBox.callBaseMethod(
this, 'dispose');
},
It is almost done, except the definition of the get and set properties which can be done like this:

//define properties
get_weakCssClass: function() {
   return this._weakCssClass;
},
set_weakCssClass: function(value) {
   this._weakCssClass = value;
},
I need to do this for all three properties.
Now, I can use this in my page after referencing it in the ScriptManager.

<script language="javascript" type="text/javascript">
  var app = Sys.Application;
  app.add_init(appInit);

  function appInit(sender, args) {
    $create(Panahy.Ajax.PassTextBox,
        { weakCssClass:
'weak', mediumCssClass: 'medium', strongCssClass: 'strong' },
        
null, null, $get('MainContent_TextBoxPassword'));
}
</script>

In this way, I don't need to set anything on the textbox.
This is still not perfect, In the next article I will demonstrate how to put this in a custom ASP.NET Control.

Implementing Custom Classes for Microsoft AJAX Library (Part 1)

This article explainis the basic steps for impplementing your own javascript class and use it in a page.
First, you need to write a script that describes the class. This example simply provides a class that verifies the length of a word to see if it has enough length to be used as a password. The file name is PasswordStrengthComponent.js

/* When working with JavaScript files in the code editor, you can add a reference to the Microsoft AJAX Library. This will ensure that your coding includes IntelliSense for the library. This is similar to the using statement in C# and the Imports statement in Visual Basic. You embed this reference in a comment at the top of your .js file. The following shows an example.
*/
/// <reference name="MicrosoftAjax.js"></reference>

// register your namespace
Type.registerNamespace("Panahy.Ajax");

//create constructor
Panahy.Ajax.PasswordStrengthComponent = function () {
    Panahy.Ajax.PasswordStrengthComponent.initializeBase(this);
}

//define class
Panahy.Ajax.PasswordStrengthComponent.prototype = {
    initialize: function () {
        //add custom initialization here
        Panahy.Ajax.PasswordStrengthComponent.callBaseMethod(this, 'initialize');
    },

    passwordStrengthClass: function (password) {
        var strPass = new String(password.toString());
        if (strPass.length &lt; 5) {
            return "Weak";
        }
        else if (strPass.length &lt; 8) {
                return "Medium";
        } else {
            return "Strong";
        }
    },

    dispose: function () {
        //add custom dispose actions here
        Panahy.Ajax.PasswordStrengthComponent.callBaseMethod(this, 'dispose');
    }
}

//register class as a Sys.Component
Panahy.Ajax.PasswordStrengthComponent.registerClass(
    'Panahy.Ajax.PasswordStrengthComponent', Sys.Component);

//notify script loaded
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Next, you reference this script file in your page within the ScriptManager:

<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference Path="Scripts/PasswordStrengthComponent.js" />
    </Scripts>
</asp:ScriptManager>

From this point the script is available and can be used in thepage as in the following example:
<script language="javascript" type="text/javascript">
    function _OnKeypress() {
        var checker = new Panahy.Ajax.PasswordStrengthComponent();
        var pass = document.getElementById("MainContent_TextBoxPassword").value;
        var strength = checker.passwordStrengthClass(pass);
         
        document.getElementById(
            "MainContent_TextBoxPassword").setAttribute("class", strength);
    }
</script>
<asp:TextBox ID="TextBoxPassword" runat="server"
        TextMode="Password" Width="200" onkeyup="_OnKeypress()" CssClass="Empty"></asp:TextBox>



Next part will take this subject one step forward.