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.

Friday, October 21, 2011

LinqToSql Count

You can pass the results of a linq query to the next statement like this one

var q = context.Products
                .Where(p => p.ProductName.StartsWith("A"))
                .Count();

and that should provide the count of products with names starting with "A". 
Further it would make no difference (performance wise) to skip theWhere statement and simply call the Count with filter as parameter, like:

var q = context.Products
                .Count(p => p.ProductName.StartsWith("B"));

or in another syntax like:

    q = (from p in context.Products
         where p.ProductName.StartsWith("C")
         select true).Count();

So, I did put a tracing into the Context.Log to see what it goes to the SQL-Server. I've got the following for all three cases:

SELECT COUNT(*) AS [value]
FROM [dbo].[Products] AS [t0]
WHERE [t0].[ProductName] LIKE @p0
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [A%]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

Placing a Web Method in a Page

In most cases, it makes sense to create a separate web service to handle your ASP.NET AJAX callbacks.
This approach generally results in clearer pages and makes it easier to debug and refine your code.
However, in some situations you may decide you have one or more web methods that are designed
explicitly for use on a single page and that really shouldn't be reused in other parts of the application. In
this case, you may choose to create a dedicated web service for each page, or you might choose to move
the web service code into the page.

Placing the web method code in the page is easy—in fact, all you need is a simple bit of cut-andpaste.
First, copy your web method (complete with the WebMethod attribute) into the code-behind class
for your page. Then, change it to a static method, and add the System.Web.Script.Services.ScriptMethod
attribute. Here's an example where the web method (named GetTerritoriesInRegion) is placed in a web
page named WebServiceCallback_PageMethods:

public partial class WebServiceCallback_PageMethods : System.Web.UI.Page
{
   [System.Web.Services.WebMethod()]
   [System.Web.Script.Services.ScriptMethod()]
   public static List<Territory> GetTerritoriesInRegion(int regionID)
   {
      // Farm the work out to the web service class.
      TerritoriesService service = new TerritoriesService();
      return service.GetTerritoriesInRegion(regionID);
   }
...
}

Next, set the ScriptManager.EnablePageMethods property to true, and remove the reference in the
<Services> section of the ScriptManager (assuming you don't want to use any non-page web services):

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

Finally, change your JavaScript code so it calls the method through the PageMethods object, as
shown here:

PageMethods.GetTerritoriesInRegion(regionID, OnRequestComplete, OnError);

The PageMethods object exposes all the web methods you've added to the current web page.
One advantage of placing a web method in a page is that the method is no longer exposed through
an .asmx file. As a result, it's not considered part of a public web service, and it's not as easy for someone
else to discover. This is appealing if you're trying to hide your web services from curious users.
Another reason you might choose to code your web methods in the page class is to read values from
view state or the controls on the page. When you trigger a page method, a stripped-down version of the
page life cycle executes, just like with the ASP.NET client callback feature you saw in Chapter 29. Of
course, there's no point in trying to modify page details because the page isn't being rerendered, so any
changes you make will simply be discarded.

Thursday, October 20, 2011

Loading a custom control at runtime

You can load a server control to your page using the constructor of the control. For example a Literal control can be loaded as follows:

plhContainer.Controls.Add(
            new Literal
            {
                Text = string.Format("{0}.{1}",
                    method.ReflectedType.FullName, method.Name)
            });



When it comes to a custom control you also want the markup code of you custom control to be loaded too. So you need to tell the Page o load it for you:


var nameBox = (NameBox) Page.LoadControl("NameBox.ascx");

Basically, you could do this at any time, but it is recommanded to do this at Page_Load the reason is that this is the best place for the control to restore its state and receive postback events. Also the binding will take place after this method. Look at my previous post for the sequence of the events and method calls when page gets loaded.
It is also recomannded to set a unique ID to that control if you need to find that later using FindControl, or some one else want to find where you have put it :-)

So, my load method will look like this:

     private void LoadMyControls()
     {
         var nameBox = (NameBox) Page.LoadControl("NameBox.ascx");
         // Give the user control a unique name by setting its ID property.
         // You can use this information to retrieve a reference to the control
         // when you need it with the Page.FindControl() method.
         nameBox.ID = "nameBox"; 
         nameBox.FirstName = "Asghar";
         nameBox.LastName = "Panahy";
         nameBox.ChangeRequest += ChangeName;
         plhContainer.Controls.Add(nameBox);
     }
When I call LoadMyControls() in Page_Load method, I see the following sequence in my output:


STARTING: MCTS._70_515.Resources._Default.Page_Init
STARTING: MCTS._70_515.Resources._Default.OnInit
STARTING: MCTS._70_515.Resources._Default.Page_Load
STARTING: MCTS._70_515.Resources.NameBox.Page_Init
STARTING: MCTS._70_515.Resources.NameBox.OnInit
STARTING: MCTS._70_515.Resources._Default.OnLoad
STARTING: MCTS._70_515.Resources.NameBox.Page_Load
STARTING: MCTS._70_515.Resources.NameBox.OnDataBinding
STARTING: MCTS._70_515.Resources.NameBox.get_LastName
STARTING: MCTS._70_515.Resources.NameBox.OnLoad
STARTING: MCTS._70_515.Resources._Default.OnPreRender
STARTING: MCTS._70_515.Resources.NameBox.OnPreRender
STARTING: MCTS._70_515.Resources.NameBox.OnUnload
STARTING: MCTS._70_515.Resources._Default.OnUnload

Notice that the custom control gets its data binded just after the page has passed Loading which is a good thing.