Tuesday, October 31, 2006

Accessing GridView's DataControlFieldCell Programmatically

How would you access the auto-generated control in the HyperLinkField (HyperLink control) and ButtonField (LinkButton or Button control) in RowDataBound event ? You will find out that FindControl() method would no longer be working since there is no concrete ID is assigned to the control, and you are not intelligent enough to know what ID will be assigned automatically by the compiler. There are two workarounds, in which the second one is new in ASP.NET 2.0.

Assuming that the HyperLinkField is at 4th column.

First Workaround

protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hl = e.Row.Cells[3].Controls[0] as HyperLink;
hl.Text = "Changing Text here";
}
}

This workaround is pretty straightward. Cells[3] refers to 4th column (index starting from 0) ; Controls[0] means the first control in that column, which is HyperLink control.

The first workaround is apparently classic way that we used in DataGrid control. But here is the another workaround, which works in different way !


Second Workaround

protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataControlFieldCell dField = e.Row.Cells[3] as
DataControlFieldCell;
HyperLinkField hlf = dField.ContainingField as HyperLinkField;
hlf.Text = "Changing Text here";
hlf.DataNavigateUrlFormatString = "nextpage.aspx?id={0}";
}
}

As you can see, I am accessing the HyperLinkField itself, and I am able to assign the DataNavigateUrlFormatString property in the RowDataBound event too. Of course, if you would like to access the control in that field, it can be done by

HyperLink hl = dField.Controls[0] as HyperLink;



Hope this helps...

SQL Server Connection Timeout !

Frustrated ! I was given an error message of "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding." when I was trying to connect to SQL Server 2000 with VS 2005. The connection string was correct and I tried several connection strings :

1. Server=ALVIN;Initial Catalog=pubs;UID=sa;
2. Server=ALVIN;uid=sa; database=pubs";
3. packet size=4096;user id=sa;data source=ALVIN;persist security info=False;database=pubs

(I used sa account for simplication, don't use it in your production site)

But none of them worked for me. I tried it in VS 2003 and unbelievably it worked! (Don't say there is any discrimination) What the heck.. Without any patience left, I saught the answer from Google and I got this link at http://msdn2.microsoft.com/en-gb/library/ms190181.aspx. It explains several causes of the problem, but one of them seemingly is the cause of my problem, which is :

"Database Engine is not listening on port 1433 because it has been changed, or because it is not the default instance, and the SQL Server Browser service is not running."

I tried to go to Client Network Utility and Server Network Utility to change my port number of TCP/IP to 1433 AND reorder it to be the first before the "Named Pipes".




After restarting the SQL Server, it eventually went fine for me. :)

Monday, October 30, 2006

New Features of my Blog

I have implemented my blogger with new Blogger Beta, and it is pretty amazing. The template in HTML is different from the classic template style. There are some new features added in this blog, such as post count in the right-hand-side sidebar, new widgets, new navigation bar. Other features such as blogs searching will be added soon. Although it is not completely nice, it nears to perfection.

For those users who use this blogger, you can visit http://beta.blogger.com/ for the version switching, or visit these sites for helps.

1. http://betabloggerfordummies.blogspot.com/index.html
2. http://groups.google.com/group/blogger-help
3. http://betabloggerfordummies.blogspot.com/


Still figuring out its features and specialities....

Saturday, October 28, 2006

Changes on my ValidTextBox Server Control

I have made some changes to my ValidTextBox server control. The changes are:

1. Supports to display error image instead of text error message when the control is invalid.
2. Supports Tooltips for error image.
3. Fixed bug of email address expression, which allows symbols.

Screenshots:






Please check http://mind.com.my/forums/1018/ShowThread.aspx#1018 for more details...

Sample Programming Interview Questions

I have found there are a set of interview books, relating to Programming - ".NET Interview Questions", "Java Interview Questions", "SQL Server Interview Questions" and so on. These questions are commonly asked by companies during their interview/recruitment process. You may take a look on sample questions at http://www.questpond.com/ , which has a lot of sample questions to be downloaded in zip format.

Some questions are tough!

[ASP.NET] Building Tag Cloud in ASP.NET

What is Tag Cloud. A tag cloud is a way to display a weighted list such that the weight of each item is reflected by the size of the item's text. Tag clouds provide a quick way for one to eyeball a list and ascertain what items are more prevalent.

Scott Mitchell has just written an article of Creating a Tag Cloud in ASP.NET. That is very cool especially you are dealing with blogging or tagging-related sites. I have tested it, and that's nothing but COOL !

Wednesday, October 25, 2006

[ASP.NET] Basic of Custom Server Control Development Part II - ParseChildren(), PersistChildren() and PersistenceMode()

Let us boils down to the three attributes that important in implementing simple properties and subproperties in the custom control development - ParseChildrenAttribute, PersistChildrenAttribute and PersistenceModeAttribute.

Default and Inner Property Persistence
Default persistence is in constrast to Inner persistence, but they are identically same for its functionality. In our control development, we may have complex properties (class). To persist them, we can use hyphenated syntax (Default Property Persistence) or nesting them within your control tags (Inner Property Persistence). Example of Inner Property Persistence,

<asp:GridView ID="GridView1" runat="server">
<HeaderStyle BorderWidth="12" />
</asp:GridView>

In the example given, the BorderWidth is the subproperties of the HeaderStyle property of GridView. To enable this inner property persistence, you need to set the ParseChildren(true) and PersistChildren(false) in your control class.

[ParseChildren(true)]
[PersistChildren(false)]
public class MyWebControl : WebControl
{
...
}


1. ParseChildrenAttribute
This attribute tells the parser to parse the parse the contents within the control tag as properties but not child controls.

To enable the inner default property persistence, you have to specify the inner default property to the second parameter of ParseChildrenAttribute.

[ParseChildren(true, "<DefaultPropertyName>")]
public class MyControl : WebControl
{
...
}


2. PersistChildrenAttribute
On the other hand, this attribute tells the designer whether the child controls of the server control should be persisted as inner child controls. Setting to false indicates inner content corresponds to properties but not to child controls.

* Therefore, the ParseChildrenAttribute and the PersistChildrenAttribute attributes use opposing conventions for the semantics of their argument. Check more difference of these two attributes at Justin Lovell's Blog - The ParseChildren and PersistChildren Attributes


3. PersistenceModeAttribute
This attribute specifies how the property of server control is persisted declaractively in ASP.NET pages. It has 3 enumerations :

EncodedInnerDefaultProperty - Specifies that the property persists as the only inner text of the ASP.NET server control. The property value is HTML encoded. Only a string can be given this designation.

InnerDefaultProperty - Specifies that the property persists in the ASP.NET server control as inner text. Also indicates that this property is defined as the element's default property. Only one property can be designated the default property.

InnerProperty - Specifies that the property persists in the ASP.NET server control as a nested tag. This is commonly used for complex objects, those that have persistable properties of their own.

Picked from http://msdn2.microsoft.com/en-us/library/system.web.ui.persistencemode.aspx

[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual TableItemStyle HeaderStyle { ... }

This indicates that the designer to persist the property as inner property. By default, it is persisted by using hyphenated syntax in control tag. To persist inner default property, you need to have

[ParseChildren(true, "<DefaultPropertyName>")]
public class MyControl : WebControl
{
...
}

and

[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual ListItemCollection Items { ... }



These three attributes are confusing, but are not undifferentiable.

Monday, October 23, 2006

My ValidTextBox is OUT !

After spending 3 days of custom control development, I have successfully developed the beta-period ValidTextBox server control. It basically integrates validator controls (RegularExpressionValidator and RequiredFieldValidator) and normal textbox control to reduce the developers' time and efforts. Here are some screenshots of the ValidTextBox server control.






Check more about the ValidTextBox server control at MIND Forum here

Thursday, October 19, 2006

[ASP.NET 2.0] Post-Cache Substitution

Post-Cache Substitution, a new feature that is not so eye-catching compared to the other new features introduced in ASP.NET 2.0 like Master Pages, Personalization, DataSource Control and etc. Basically, Post-Cache Substitution allows developers dynamically update the contents of output-cached portions (eg. header, footer). When a header user control (header.ascx) is given the following directive

<%@ OutputCache Duration=3600 VaryByParam=none %>

It tells the page to be partially cached for an hour (3600 seconds). If there is current date and time showing in the header section, it is unlikely that the time will be updated for every second since it is cached for an hour long.

There are common 2 ways of implementation of Post-Cache Substitution solves this problem for you - Use of Substitution Control and Substitution API.


1. Substitution Control
This control tells the page not to cache the section for its dynamic contents. Every contents in the control would not be cached.

1. To use this control, drag the Substitution Control from VS 2005's ToolBox and drop it onto your WebForm.

2. The control has a MethodName property, which is assigned to a static method. In the code-behind, define a static method that accepting a page context as parameter.

public static string GetCurrentDateTime(HttpContext context)
{
return DateTime.Now.ToLongTimeString ();
}

3. Back to Design View. In the control's property window, assign GetCurrentDateTime to MethodName property. This ascertains that subsequent requests to the page call the method again to generate dynamic content.



2. Substitution API
This implementation uses the in-lline code, by calling the Response.WriteSubstitution() method that accepting name of method as parameter. Thus, in your ASPX HTML view, add this

<% Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetCurrentTime)); %>

It would change client-side cacheability to server cacheability, which the dynamic contents are not cached on clients.

Wednesday, October 18, 2006

[ASP.NET] Specifying DefaultButton in MasterPage

In normal ASP.NET 2.0, we can easily assign the DefaultButton property in the

<form runat="server" DefaultButton="btnSearch">


But what if we would like to make two different buttons from two pages that inheriting the MasterPage to be DefaultButton? It might not be working using the way above because MasterPage because it is publicly shared by its content pages. You, however, have to programmatically assign the DefaultButton in each of the content page.

In content Page,

this.Form.DefaultButton = "MyDefaultButton";

This is not the way of assigning the ID of button to DefaultButton property. Use this way,

this.Form.DefaultButton = MyDefaultButton.UniqueID



Cheeers

[ASP.NET] Redirecting Page after Emiting JS in Code-behind

To emit the JavaScript in code-behind in ASP.NET, we use RegisterStartupScript() or RegisterClientScriptBlock() method. But when we would like to redirect user to a specified page after the JS pop-up, we probably would use this (written in VS.NET 2003, use ClientManager for VS 2005)

string strScriptName = "AlertScript";
string strMessage = "There is an error";

string strScript += strMessage + "')<"
strScript += "/"
strScript += "script>"

if(!Page.IsStartupScriptRegistered(strScriptName))
objPage.RegisterStartupScript(strScriptName, strScript)

Response.Redirect("error.aspx");

If you run the code, you will notice that you will be redirected to the error.aspx WITHOUT being prompted the error message dialog box of "This is an error" because Response.Redirect() forces the browser not to render the HTML (sending a header to client to cause client to redirect to specified URL).

To overcome this problem, replace the Response.Redirect("error.aspx"); with

Response.AppendHeader("refresh","0;Url='error.aspx'");

Instead of redirecting the page, the browser would simply refresh the page within 0 second and "redirecting" to the error.aspx, as specified in the Url parameter.

Tuesday, October 17, 2006

[ASP.NET] Basic of Custom Server Control Development Part I

Developing custom server control in ASP.NET is fun! You are flexible to develop it either inheriting the existing ASP.NET server controls like Button, HyperLink, BoundField or create you own control by inheriting Control/WebControl classes from System.Web.UI namespace. There are dozens of cool and fabulous custom server controls developed by third-parties like Metabuilder or ExcentricWorld. I like to develop the custom server control because the tailored controls can specifically accomplish some jobs that normal shipped-in ASP.NET server controls can't. It serves the purpose on your needs.

There are basic concepts/rules in custom server control development in ASP.NET like :

1. Derive your control class from System.Web.UI.Control if your control is dealing with non-visual elements or merely render as HTML output. For instance, META tag. Otherwise, your class should inherit from System.Web.UI.WebControls class if your control is built to have visual appearance to the client.

2. Do not override the Render() method of in your control if it is inheriting from System.Web.UI.WebControls class because the method is responsible in rendering the outer tag and control styling to the output stream. Override its RenderContent() method instead!

protected override void RenderContent(HtmlTextWriter writer)
{
writer.Write("Test");
}


3. When your control inherting the System.Web.UI.WebControls, its outer tag is <span> by default. You can get rid of this and render any outer tags you want by overriding its HtmlTextWriterTag.TagKey or TagName (non-standard HTML tags).

protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Input; }
}

or

public Button() : base(HtmlTextWriterTag.Input)
{ }



4. Check whether the control is in the <form runat="server"> by

if (Page != null)
Page.VerifyRenderingInServerForm(this);


in either AddAttributesToRender() or Render()/RenderContent() method.


5. By default, the tag prefix of your custom server control would be auto-generated. For instance, when you drag and drop your control, the tag would be something like

<cc1:CustomMeta ID="CustomMetaTag1" runat="server" />

As you see, the "cc1" gives no meaning. You can add your own tag prefix by adding TagPrefixAttribute in the assemblyinfo.cs file.

using System.Web.UI;
[assembly:TagPrefix("SimpleControl", "Alvin")]

Now, it would become like

<Alvin:CustomMeta ID="CustomMetaTag1" runat="server" />


6. Take note of rendering methods of System.Web.UI.Control class

public void RenderControl(HtmlTextWriter writer) {
if (Visible) {
Render(writer);
}
}

protected virtual void Render(HtmlTextWriter writer) {
RenderChildren(writer);
}

protected virtual void RenderChildren(HtmlTextWriter writer) {
foreach (Control c in Controls) {
c.RenderControl(writer);
}
}


It is wise to call the base class's methods if you intend to override the method like RenderChildren method to ensure its child controls are recursively rendered.

protected override void RenderChildren(HtmlTextWriter writer)
{
base.RenderChildren(writer);

// do your stuff
}



7. To restrict the control to have NO CHILD CONTROLS, you need to return EmptyControlCollection(this) to the overidden CreateControlCollection() method.

protected override ControlCollection CreateControlCollection() {
return new EmptyControlCollection(this);
}


By doing that, no child controls/tags are allowed.

// Allow
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server" />

// Not allow !
<Alvin:CustomMeta ID="CustomMetaTag1" runat="server"></Alvin:CustomMeta>

Saturday, October 14, 2006

Go for Google or Microsoft?

Cliff, who has been offered by Google and Microsoft is in trouble! He is in hestitation whether to work for Google or Microsoft, He posted a dicussion topic of Microsoft or Google? to ask Slashdot-ers about both companies' working environments and their thought about the companies. It is interesting to see the commenters posted their opinions about Google and Microsoft's working environment, working hours, management styles, pressure, corporate culture, benefits and so on, respectively.

Google or Microsoft? Hard to choose even to me.

Tips and Tricks on cloning data-bound controls

Here are some tips and tricks on cloning the Data-Bound controls.

Cloning DataGrid/GridView
It is common mistake when you would like to copy the assigned DataGrid's DataSource to another DataGrid's datasource like

DataGrid2.DataSource = (DataSet)DataGrid1.DataSource;

You would simply get the NullReference exception. It seems work but it doesn't. A better way is store the needed DataSet to Cache or Session and reuse it for subsequent data binding.

Object objDS = Cache["MyDS"];
if(objDS != null)
{
DataSet ds = (DataSet)objDS;
DataGrid1.DataSource = ds;
DataGrid2.DataSource = ds;
}
else
{
DataSet ds = new DataSet();
// open conn, fill the DS;
DataGrid1.DataSource = ds;
DataGrid2.DataSource = ds;

Cache["MyDS"] = ds;
}

THERE is another way cloning the content of Grid by rendering its HTML contents to HtmlTextWriter. Try to put this code in the Button's Click event.

StringBuilder strBuilder = new StringBuilder();
StringWriter writer = new StringWriter();

HtmlTextWriter textWriter = new HtmlTextWriter(writer);
strBuilder = writer.GetStringBuilder();
dgrdAuthors.RenderControl(textWriter);

string strContent = strBuilder.ToString();
Response.Write(strContent);


Once you click the button, the cloned Grid appears. This code is particularly useful especially you would like to send the content of Grid over email.


.....
objMail.Body = strContent
objMail.BodyFormat = MailFormat.Html
....



Cloning DropDownList/CheckBoxes/RadioButtonList
How do you make two DropDownLists, which bound to a datasource to have identical items? The very basic method is use of DataSet like

DropDownList1.DataSource = ds;
DropDownList1.DataTextField = "MyText";
DropDownList1.DataValueField = "MyValue";
DropDownList1.DataBind();

DropDownList2.DataSource = ds;
DropDownList2.DataTextField = "MyText";
DropDownList2.DataValueField = "MyValue";
DropDownList2.DataBind();

It works fine. No complain. What if you use forward-only IDataReader for performance wise? You may need to have two IDataReaders for each DDL's data-binding. Here is another trick where only one DataReader is needed.

reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
DropDownList1.DataSource = reader;
DropDownList1.DataTextField = "MyText";
DropDownList1.DataValueField = "MyValue";
DropDownList1.DataBind();
reader.Close();

// I am cloning the ListItemCollections of DDL1 to DDL2
DropDownList2.DataSource = DropDownList1.Items;
DropDownList2.DataTextField = "Text";
DropDownList2.DataValueField = "Value";
DropDownList2.DataBind();



Much simpler, much faster, much neat !

Friday, October 13, 2006

Browser DOM Supports and Compatibility Issues

I occasionally get some earful from other people how hard to develop an AJAX application. Well, it isn't that hard if you use on-ready AJAX development tools such as Atlas. Nevertheless, you may be cracking your head on writing remote scripting from ground up because there are few issues need to be taken care.

Other than the checking the types of the browser, you also need to concern about the DOM supports the particular browser can support. For instance, the innerText property of < span > is not supported in FireFox, you have to use textContent property or universal supported innerHTML property. Here are the listing of sites that you may need to check the DOM that the layout engines in each browser can support.


Links
1. Web browser HTML support
http://www.webdevout.net/browser_support_html.php

2. Web browser DOM support
http://www.webdevout.net/browser_support_dom.php

3. DOM Support in Mozilla
http://www.mozilla.org/docs/dom/mozilla/

4. Comparison of layout engines (DOM)
http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28DOM%29

5. Common Differences Among IE and Mozilla
http://www.htmlgoodies.com/primers/jsp/article.php/3624446

[ASP.NET] Serializing/Deserializing Passing Objects Across Pages with LosFormatter

On our ordinary basis, we pass the values or object values across two pages using Session, Form Posting, PreviousPage reference in ASP.NET. But however, we could not able to append the object to the query string (unless you use the Session state instead). There is another alternative way - passing the serialized the object values into string presentation in query string.

How ?? First of all, are you familiar with this ?


< input type="hidden" name="__VIEWSTATE" value="dDwxMzIwMTI1MjYwO3Q8O2w8aTwxPjs+O2w8dDw7bDx
pPDE+Oz47bDx0PHA8cDxsPE5hdmlnYXRlVXJsOz47b
DxXZWJmb3JtMi5hc3B4P3ZhbHVlPWJEeDBhR2x6T3o
0PTs+Pjs+Ozs+Oz4+Oz4+Oz5RXn3JAFz8V0ozE1lmu
5B1K2D7xw==" / >


If you do, that's good. It is ViewState, the hidden field that stores control state, which the state values (eg. object values, primitive type values) are serialized and deserialized into base-64 string using LosFormatter. Similarly, this approach can be used to serialize the object and pass it to the next page in query string.

The following example shows you how to pass the serialized ArrayList to the next page using LosFormatter.

Code
Firstpage.aspx

System.IO;
System.Collections;

private void Page_Load(Object sender, EventArgs e)
{
ArrayList ary = new ArrayList();
ary.Add("this");

System.Web.UI.LosFormatter formatter = new System.Web.UI.LosFormatter();
StringWriter writer = new StringWriter();

formatter.Serialize(writer,ary);
HyperLink1.NavigateUrl = "secondpage.aspx?value=" + writer.ToString();
}


Check the URL in the HyperLink control in Firstpage.aspx, it would be something like

http://localhost/WebTest/secondpage.aspx?value=bDx0aGlzOz4=


The ArrayList object has just been serialized ! How to deserialize the object back?


Secondpage.aspx

System.IO;
System.Collections;

private void Page_Load(Object sender, EventArgs e)
{
System.Web.UI.LosFormatter formatter = new System.Web.UI.LosFormatter();
ArrayList aryL = (ArrayList)formatter.Deserialize(Request.QueryString["value"]);

Response.Write(aryL[0]);
}


* Be noted, you need to explicitly specify the System.Web.UI.LosFormatter in the object instantiation. You will get the undefined Serialize()/Deserialize() method, otherwise. Watch out the number of characters supported in the URL. Not all objects are suitable to be serialized, only relatively small-size objects are appropriate to do so.


The LosFormatter class is extremely useful especially you override the SaveViewState() or LoadViewState() of the Page class/ Control, you need this class to do the serialization or deserialization of control states.

Thursday, October 12, 2006

[.NET 2.0] Foreach-ing Arrays with Iterator & Generics

Prior to the .NET 2.0, we have to use for statement to loop each of the element in the array. C# 2.0 offers you another one - Iterator, a familar word that in the Design Pattern, a method that can be used to enumerate through collection of values such as array and return each of the element in turn. For instance,

Code

string[] aryNames = {"Alvin","Westley","Howard"};

foreach(string str in IterateMe(aryNames))
Response.Write(str + " ");


private IEnumerable IterateMe(string[] str)
{
int iLength = str.Length;
for(int index=0;index < iLength;index++)
yield return str[index];
}
Output :
Alvin Westley Howard


Your Iterator method has to return either IEnumerable or IEnumerator type to the caller function, which in turn contains the element value of current iteration. Make it more usable with generic,

Code:

string[] aryNames = {"Alvin","Westley","Howard"};
int[] iValues = {1,2,15,4,6,9};

foreach(string str in IterateMe< string >(aryNames,true))
Response.Write(str + " ");

foreach(int value in IterateMe< int >(iValues,true))
Response.Write(value + " ");


private IEnumerable IterateMe< T >(T[] str, bool sorting)
{
if(sorting && !typeof(T).Name.Equals("Object"))
Array.Sort(str);

int iLength = str.Length;
for(int index=0;index < iLength;index++)
yield return str[index];
}

Output:
Alvin Howard Westley
1 2 3 6 9 15

Wednesday, October 11, 2006

My Revamped Blog !

I have just revamped my blog by changing the page template to my favourite color and font family + size combinations.

Testing..


Response.Write("Welcome to my newly-revamped blog!");

Tuesday, October 10, 2006

[AJAX] IE 7 getting Native XMLHTTPRequest object

Programming AJAX Web application would be in trouble when users turning off the ActiveX support in IE. The sentence of

var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

would not be working. But luckily, there is native XMLHTTPRequest object like what non-IE browsers do.

var xmlHttp = new XMLHttpRequest();


No ActiveX object is needed, so far. Here is the code needs to be added to check the support of native XMLHTTPRequest object

if (window.XMLHttpRequest)
{
// If IE7, Mozilla, Safari, etc: Use native object
var xmlHttp = new XMLHttpRequest();
}
else
{
if (window.ActiveXObject){
// use the ActiveX control for IE5.x and IE6
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}

[ASP.NET] ASP.NET's FREE Components List

Jason'd compiled a long but yet comprehensive list of free components of ASP.NET, ranging from data-bound controls, graphing controls, navigation controls to templating and reporting controls..

Check Free Components for ASP.NET for more detailed info. (Check user comments for some other useful controls too)


Hunting for more !

Monday, October 09, 2006

[My Project] LVUtilities Lib v1.109 Updates : XmlHelper class

I have just done the following changes in this LVUtilities Lib v1.109

New XMLHelper class
1. ReadValuesByXPath()
2. ReadElementValues()
3. ReadElementList()
4. ReadSingleElementValue()
5. ReadAttributeValue()

6. UpdateValuesByXPath()
7. UpdateSingleValueByXPath()

8. InsertAttributeByXPath()
9. InsertElementByXPath()

10.RemoveAttributeByXPath()
11.RemoveElementByXPath()


Changelog
1. Overloaded Generic IsDBNullValue<>() method
2. Improve the string manipulation performance in string replacement



Download the library + examples here

Saturday, October 07, 2006

Updates : SecurityHelper and ValidationHelper classes

I have enhanced the SecurityHelper and the ValidationHelper classes to support :

1. ValidationHelper class
The IsValidStateNames(), IsValidPhoneNO() , IsValidHPNO(), IsValidICNO(), IsValidPostalCode() are no longer limited to Malaysia context. For instance, to validate the phone number of US,

if(ValidationHelper.IsValidPhoneNO(strInput,"(999)999-9999"))
// true or false

in which the "(999)999-9999" is the input mask pattern that used to validate the US phone number format.


2. SecurityHelper class
The CompareValueToHash() method can now accept both string parameters of user input and hashed string. For instance,

string strPassword = SecurityHelper.GenerateHashInString("abc");
if(SecurityHelper.CompareValueToHash("abc",strPassword))
// true or false



Download Examples and Library here

Friday, October 06, 2006

[.NET] Debugger, dont STEP INTO my method !

Had you experienced whenever you debug your application using the step-into feature (F11), the debugger will go through the implementation of the methods being called, which you might not want it to. How do you "tell" the debugger to skip the method and move on to next statement? Here is the answer.

using System.Diagnosis;

[DebuggerStepThrough]
public void MyMethod()
{
....
}


Be noted, the [DebuggerStepThrough] attribute can be used in the get/set of property, too.


public string MyProperty
{
[DebuggerStepThrough]
get { }
}



MyMethod : "Thanks for skipping over me, Debugger !"

Thursday, October 05, 2006

[AJAX] AJAX Tutorials !

Planning to develop the AJAX app on the fly? Here are AJAX tutorials links that you can't afford to lose....

1. 130+ AJAX Tutorials [AjaxMatters]
2. Top 126 AJAX Tutorials
3. 60 Tutorials of AJAX [Max Kiesler]

[My Project] My Helper library is OUT !

I have been working on creating a simple library which consists of 5 major helper classes in this version as following:

1. ValidationHelper class

a. IsValidFileName()
b. IsValidNumeric()
c. IsDBNullValue()
d. IsValidDateFormat()
e. IsAlpahbet()
f. IsAlphaNumeric()
g. IsValidUserName()
h. IsValidName()
i. IsValidStateName() // Malaysia Context only
j. IsValidPhoneNo() // Malaysia Context only
k. IsValidHPNo() // Malaysia Context only
l. IsValidICNo() // Malaysia Context only
m. IsValidPostalCode() // Malaysia Context only
n. IsValidEmail()



2. SecurityHelper Class

a. GenerateHash() // MD5, SHA1, SHA256, SHA384, SHA512
b. GenerateHashInString()
c. CompareValueToHash()
d. TDESEncrypt() and TDESDecrypt() // Triple DES


3. MailHelper Class

a. SendMessage()


4. HttpPostHelper Class

a. SendRequest()


5. ClientScriptHelper Class (ASP.NET only)

a. ShowMessage()



* I am working on the XmlHelper and FileHelper classes in coming release.


Download
Download Library DLL and Examples : http://www.megaupload.com/?d=1G96G4U9

Wednesday, October 04, 2006

[ADO.NET] 3 ways closing DataReader & Connection..

These are the 3 common ways I use to close the XDataReader and DB Connection...

1. Use CommandBehavior.CloseConnection

SqlDataReader reader = null;

try
{
   reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

   // do stuff
}
catch(Exception ex)
{
   // logging error
}
finally
{
   // conn will be closed when reader is closed
   reader.Close();
}


2. Explicitly Close DataReader and Connection

SqlDataReader reader = null;

try
{
   reader = cmd.ExecuteReader();

   // do stuff
}
catch(Exception ex)
{
   // logging error
}
finally
{
   // conn will be closed when reader is closed
   reader.Close();
   conn.Close();
}


3. Use Using Statement

using(SqlConnection con = new SqlConnection(<connection string>))
{
   using(SqlCommand cmd = new SqlCommand(<query>,conn))
   {
      using(SqlDataReader reader = cmd.ExecuteReader())
      {
         // do stuff
      }
   }
}


The first one is my preference, what about you?

[.NET 2.0] New Methods / Operator in .NET 2.0

I summarize some of the useful new methods and operator introduced in .NET 2.0 here...

1. String.Contains()

Old way in .NET v1.X
string str = "Today is monday";

if(str.IndexOf("is")!= -1)
// do stuff


New way in .NET 2.0
string str = "Today is monday";
if(str.Contains("is"))
// do stuff


2. String.StartsWith()

Old way
string str = "Alvin Chooi";
if(str.IndexOf("Al")==0)
// do stuff


New way
string str = "Alvin Chooi";
if(str.StartsWith("Al"))
// do stuff


3. String.EndsWith()

Old way
string str = "Alvin Chooi";
if(str.IndexOf("Al")== str.Length-2)
// do stuff


New way
string str = "Alvin Chooi";
if(str.EndsWith("Al"))
// do stuff


4. String.IsNullOrEmpty()

Old way
string str = "Alvin Chooi";
if((str!=null) && (str.Length > 0))
// do stuff


New way
string str = "Alvin Chooi";
if(!String.IsNullOrEmpty(str))
// do stuff


5. TryParse()

Old way
int iValue;
try
{
iValue = Int32.Parse("2x");

return true;
}
catch(Exception ex)
{
return false;
}


New way
int iValue
bool isValid = Int32.TryParse("2x",out iValue);


6. Non-null operator (??)

Old Way
string str = null;

if(str!=null)
Response.Write(str);
else
Response.Write("It is null");


New way
Response.Write(str?? "It is null");


7. Eval() & Bind() in ASP.NET 2.0

Old way
<%# DataBinder.Eval(Container.DataItem,"MyField") %>

New way
<%# Eval("MyField") %> // one-way binding
<%# Bind("MyField") %> // two-way binding



Codes become lesser and lesser... (But why our work will never be lessen?, ha)

Tuesday, October 03, 2006

[ASP.NET] RequiredFieldValidator + OnClientClick issue

OnClientClick property was introduced in ASP.NET 2.0 to eliminate the need of developers to add the client-side "onclick" to a control programmatically. For instance,

JS script

function ConfirmMe()
{
   return confirm("Do you want to proceed?");
}


ASPX

<asp:TextBox id="txtName" runat="server"/>
<asp:Button id="btnSubmit" OnClientClick="return ConfirmMe()" Text="Submit" runat="server"/>


Well, that is pretty straightforward. BUT, it goes weird when you have a validator control (eg. RequiredFieldValidator) that is used to validate the "txtName" textbox server control. For instance,


<asp:TextBox id="txtName" runat="server"/>

<asp:RequiredFieldValidator id="rq1" ControlToValidate="txtName" ErrorMessage="Name cannot be blank" Display="Dynamic" runat="server"/>

<asp:Button id="btnSubmit" OnClientClick="return ConfirmMe()" Text="Submit" runat="server"/>


Whenever you press the button with no textbox value, the client-side confirmation dialog will be invoked first before the validator message is able to show up. This isn't what we expected it to behave. I tried several ways to overcome this problem, including using CLIENT CALLBACK, disabling the CauseValidation, but it failed. Finally, I was able to find a solution by adding JUST ONE line in the JS script.

function ConfirmMe()
{
   if(Page_ClientValidate())
      return confirm('Do you want to proceed?');

   return false;
}



Another discovery today !

Validator for CheckBox/CheckBoxList

By default, there is no validator server control available to validate the validity of checkbox in ASP.NET. On the basis practice, I have to use CustomValidator control or using pure client-side JS or the postback checking on server-side. But to ease the job, you can try Custom Checkbox Validator, created by Microsoft MVP, Scott Mitchell.

URL : http://aspnet.4guysfromrolla.com/articles/092006-1.aspx



IsValid? True !

About SqlDataSource control

I've been running a problem of losing the selected items in a listbox, which is bound to the SqlDataSource control on every postback. The code is :


<asp:ListBox ID="lstBox" runat="server" CssClass="listbox-flat" DataSourceID="objSQL" DataTextField="userFullName" DataValueField="RID" SelectionMode="Multiple" Width="335px" Enabled="False"></asp:ListBox>

<asp:SqlDataSource ID="objSQL" runat="server" ConnectionString="<%$ ConnectionStrings:dbConnectionString %>" SelectCommand="SELECT * FROM Table1"> </asp:SqlDataSource>


As far as I remember, the selections of ListBox SHOULD be retained on the postback since the ViewState of the control will be saved in the SaveViewState event after the binding, but the thing goes weird unexpectedly :(. Since the automatic databinding performed by the SqlDataSource takes place in the Page_PreRender event (You can check it by using Page Tracing). Here is the screenshot:


* The ListBox is bound to the DataSource control.

Eventually, I used another way round by programmatically binding the ListBox in that PreRender event with IsPostBack checking. (No choice, this is the best way I could think of, I will find out the cause of the problem later)

Steps
1. Set the DataSourceID property of ListBox to empty (So that it would not be bound to the SqlDataSource until runtime)

2. Obtain the SqlDataSource's IEnumerable collection by calling the DataSource's Select() method with no argument.

3. Call the ListBox's DataBind() method


Code

protected void Page_PreRender(Object sender, EventArgs e)
{
if(!IsPostBack)
{
   lstBox.DataSourceID = String.Empty;
   lstBox.DataSource = objSQL.Select(DataSourceSelectArgument.Empty);
   lstBox.DataBind();
}
}


Good Practice
For ordinary data binding operations like binding DataGrid, ListBox, DropDownList, etc, we normally perform in Page_Load() event. Actually, we can do the binding in the Page_PreRender event (bind the data-bound controls as late as possible) before the controls are about to be rendered.

Do always check IsPostBack before performing any data binding to reduce the roundtirp to server.


Digging into detailed observations...