The CustomValidator and the EventHandler ServerValidateEventArgs / Customized TextBox control
This is more like a continuous article to the previous post.
In this article, I am going to explain a bit how to intergreate the CustomValidator and the ServerValidEventArgs event handler into the TextBox control, and after the integration, you don't need to explicitly have a CustomValidator and the ServerValidEventArgs in the Aspx page, all you need to do is to create a ServerValidEventArgs event for the instance of TextBox control and the CustomValidator will be created accordingly automatically by the TextBox control.
In this example, OTextBox is the customized version of TextBox that integrated with a CustomValidator and its ServerValidEventArgs.
Here is the code for: OTextBox.cs
public class OTextBox : System.Web.UI.WebControls.TextBox
{
// This is the CustomValidator that will be added to the OTextBox instance if its
// server validate event handler is created by the user.
private CustomValidator _customValidator;
// The server validate event handler.
public event EventHandler CustomServerValidate;
/// <summary>
/// Called by the ASP.NET page framework to notify server controls that
/// use composition-based implementation to create any child controls
/// they contain in preparation for posting back or rendering.
/// </summary>
protected override void CreateChildControls()
{
base.CreateChildControls();
//CustomValidator
_customValidator = new CustomValidator();
_customValidator.ID = "CustomValidator" + this.ID;
_customValidator.ControlToValidate = this.ID;
_customValidator.Display = ValidatorDisplay.None;
_customValidator.ErrorMessage = "Error Message for CustomValidator";
_customValidator.ServerValidate += new ServerValidateEventHandler(_customValidator_SV);
// Add the CustomValidator to the page
Controls.Add(_customValidator);
}
/// <summary>
/// Handles the ServerValidate event of the _customValidator control.
/// </summary>
/// <param name="source">The source of the event.</param>
/// <param name="args">The instance containing the event data.</param>
private void _customValidator_SV(object source, ServerValidateEventArgs args)
{
// If this server validate event handler has been created by the user
if (CustomServerValidate != null)
CustomServerValidate(source, args);
}
/// <summary>
/// Outputs server control content to a provided object and stores
/// tracing information about the control if tracing is enabled.
/// </summary>
/// <param name="writer">The object that receives the control content.</param>
public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
{
base.RenderControl(writer);
// Render the CustomValidator
if (this.CustomServerValidate != null)
_customValidator.RenderControl(writer);
}
}
How to use this customized control? Very simple, here is another example:
Assume that the OTextBox's namespace is Example.Mycontrols, so add the section below to the Web.Config file in order to access the customized control as <uc:ControlName ID="Balala" runat="server" />:
<pages>
<controls>
<add tagPrefix="uc" namespace="Example.MyControls" assembly="Example"/>
</controls>
</pages>
And in Default.aspx page, add the OTextBox instance:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Example.Default" %>
<html>
<head id="Head" runat="server" />
<title></title>
<body>
<form id="DefaultForm" runat="server">
<uc:OTextBox ID="TxtExample" runat="server" />
</form>
</body>
</html>
In Default.aspx.cs code-behind, create the event handler, and associate it with a method:
namespace Example
{
public partial class Default : System.Web.UI.Page
{
/// <summary>
/// Raises the event to initialize the page.
/// </summary>
/// <param name="e">An EventArgs that contains the event data.</param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
TxtExample.CustomServerValidate += new EventHandler(TxtExample_CustomServerValidate);
}
/// <summary>
/// Handles the CustomServerValidate event of the TxtEmailAddress control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The instance containing the event data.</param>
public void TxtExample_CustomServerValidate(object sender, ServerValidateEventArgs e)
{
if (Something is OK)
e.IsValid = true;
else
e.IsValid = false;
}
}
}
Then it is done, isn't that simple, and you can add some code to this TxtExample_CustomServerValidate method, and it will validate it when Page.Validate() occurs, is that cool?
Thanks!
My customized TextBox control with various validators integrated, is it convenient for you as well?
It is so boring that when every time i create a form that need to be filled in by the user, for example, the Password field, and Re-Password field, E-mail Address field and Comfirm E-mail Address field, i need to create the RequiredFieldValidator, RegularExpressionValidator, and CompareValidator for each of them. That is really messy and redundent for the Aspx pages.
So, I am thinking about to customize the default TextBox control and write a my own OTextBox control with all the three validators integrated inside the OTextBox.
By doing this, OTextBox can enable me, if I want an OTextBox instance that need to have the regular expression to validate its input before submit, just set its ValidateRegularExpression propertity to a pre-defined RegularExpressionType, and nothing more to add in the Aspx pages.
Here is the code:
--------------------------------------------------------------------------------
OTextBox.cs
public class OTextBox : System.Web.UI.WebControls.TextBox
{
private RequiredFieldValidator _requiredValidator;
private CompareValidator _compareValidator;
private RegularExpressionValidator _regularValidator;
// ValidatorCalloutExtender is a pop up box with the error message when the error occurs
// with its validator and this ValidatorCalloutExtender is from AjaxControlToolkit.
private ValidatorCalloutExtender _requiredCalloutExtender;
private ValidatorCalloutExtender _compareCalloutExtender;
private ValidatorCalloutExtender _regularCalloutExtender;
/// <summary>
/// If this propertity is set to true, then the RequiredFieldValidator
/// will be added and validate the text field in current control.
/// </summary>
public bool Required
{
set{ this.ViewState["Required"] = value; }
get
{
if (this.ViewState["Required"] != null)
return (bool)this.ViewState["Required"];
return false;
}
}
/// <summary>
/// If this propertity is set to a value, then the CompareValidator
/// will be added and compare the text field in current control
/// to the control that is given by this propertity.
/// </summary>
public string CompareToTextBoxID
{
set{ this.ViewState["CompareToTextBoxID"] = value; }
get
{
if (this.ViewState["CompareToTextBoxID"] != null)
return (string)this.ViewState["CompareToTextBoxID"];
return string.Empty;
}
}
/// <summary>
/// If this propertity is set to a value, then the CompareValidator
/// will be added and compare the text field in current control
/// to the control that is given by this propertity.
/// </summary>
public RegularExpressionType ValidateRegularExpression
{
set{ this.ViewState["ValidateRegularExpression"] = value; }
get
{
if (this.ViewState["ValidateRegularExpression"] != null)
return (RegularExpressionType)this.ViewState["ValidateRegularExpression"];
return RegularExpressionType.None;
}
}
/// <summary>
/// Nothing much, the constructor.
/// </summary>
public void OTextBox
{
// Can put something here
}
/// <summary>
/// will create all the necessary controls and add them to the Controls collection
/// </summary>
protected override void OnInit(EventArgs e)
{
// For RequiredValidator
if (this.Required)
{
_requiredValidator = new RequiredFieldValidator();
_requiredValidator.ControlToValidate = this.ID;
_requiredValidator.ID = "RequiredValidator" + this.ID;
_requiredValidator.Display = ValidatorDisplay.None;
_requiredValidator.ErrorMessage = "Your Error Message For RequiredValidator";
_requiredCalloutExtender = new ValidatorCalloutExtender();
_requiredCalloutExtender.TargetControlID = _requiredValidator.ID;
_requiredCalloutExtender.ID = "RequiredCallout" + this.ID;
_requiredCalloutExtender.HighlightCssClass = "YourCssForThisPopUp";
_requiredCalloutExtender.Width = 100; // The width you want this pop to be
Controls.Add(_requiredValidator);
Controls.Add(_requiredCalloutExtender);
}
// For CompareValidator
if (!string.IsNullOrEmpty(this.CompareToTextBoxID))
{
OTextBox txtBoxNeedToCompare = (OTextBox)this.Parent.FindControl(this.CompareToTextBoxID);
if (txtBoxNeedToCompare != null)
{
_compareValidator = new CompareValidator();
_compareValidator.ControlToValidate = this.ID;
_compareValidator.ControlToCompare = this.CompareToTextBoxID;
_compareValidator.ID = "CompareValidator" + this.ID;
_compareValidator.Display = ValidatorDisplay.None;
_compareValidator.ErrorMessage = "Your Error Message For CompareValidator";
_compareCalloutExtender = new ValidatorCalloutExtender();
_compareCalloutExtender.TargetControlID = _compareValidator.ID;
_compareCalloutExtender.ID = "CompareCallout" + this.ID;
_compareCalloutExtender.HighlightCssClass = "YourCssForThisPopUp";
_compareCalloutExtender.Width = 100; // The width you want this pop to be
Controls.Add(_compareValidator);
Controls.Add(_compareCalloutExtender);
}
}
// For RegularExpressionValidator
if (this.ValidateRegularExpression != RegularExpressionType.None)
{
_regularValidator = new RegularExpressionValidator();
_regularValidator.ControlToValidate = this.ID;
_regularValidator.ID = "RegularExpressionValidator" + this.ID;
_regularValidator.Display = ValidatorDisplay.None;
_regularValidator.ErrorMessage = "Your Error Message For RegularExpressionValidator";
switch(ValidateRegularExpression)
{
case RegularExpressionType.Email:
_regularValidator.ValidationExpression = "Your regular express for email";
break;
case RegularExpressionType.Domain:
_regularValidator.ValidationExpression = "Your regular express for domain";
break;
case RegularExpressionType.PhoneNumber:
_regularValidator.ValidationExpression = "Your regular express for phone number";
break;
// Can add more if needed.
}
_regularCalloutExtender = new ValidatorCalloutExtender();
_regularCalloutExtender.TargetControlID = _regularValidator.ID;
_regularCalloutExtender.ID = "RegularCallout" + this.ID;
_regularCalloutExtender.HighlightCssClass = "YourCssForThisPopUp";
_regularCalloutExtender.Width = 100; // The width you want this pop to be
Controls.Add(_regularValidator);
Controls.Add(_regularCalloutExtender);
}
}
/// <summary>
/// Render these controls
/// </summary>
public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
{
base.RenderControl(writer);
// For RequiredValidator
if (this.Required)
{
_requiredValidator.RenderControl(writer);
_requiredCalloutExtender.RenderControl(writer);
}
// For CompareValidator
if (!string.IsNullOrEmpty(this.CompareToTextBoxID))
{
OTextBox txtBoxNeedToCompare = (OTextBox)this.Parent.FindControl(this.CompareToTextBoxID);
if (txtBoxNeedToCompare != null)
{
_compareValidator.RenderControl(writer);
_compareCalloutExtender.RenderControl(writer);
}
}
// For RegularExpressionValidator
if (this.ValidateRegularExpression != RegularExpressionType.None)
{
_regularValidator.RenderControl(writer);
_regularCalloutExtender.RenderControl(writer);
}
}
}
RegularExpressionType.cs
public enum RegularExpressionType
{
None = 0,
Email = 1,
PhoneNumber = 2
}
--------------------------------------------------------------------------------
I only showed an example of how to customize the TextBox control, actually, there are still a lot of useful functionalities that can be integrated, such as ValidationGroup, and other extra stuff that can be extended to the default TextBox control.
Hope this article can help someone and reduce the amount of work.
Customized WebBrowser control
WebBroswer control which is introduced since .Net 2.0 enables us to have a web browser in our application easily. When I use it, I encountered some issues that can not be handled by the default WebBrowser. For example, It does not have enough events for certain situations, such the event DocumentComplete, nor enough functionalities that as the regular browsers do, such block unwanted pop ups.
Will continue on this post later today or tomorrow.
DO NOT drive to OSLO in the morning, use train instead, traffic is a hell
Nice, very nice, the morning traffic to Oslo is nothing different than the traffic in Beijing.
Headache, and slow.
Living in a city (OK, OK, it is a town) 20Km far away from Oslo, In the past few weekdays, I got up at around 6:30, and left home at 7, just because of trying to avoid the terrible traffic, however, I still need an hour to reach my office, it is only 20Km!!
CommunicationException was unhandled by user code / There was an error while trying to serialize parameter http://tempuri.org/:serviceList
Error Code:
There was an error while trying to serialize parameter http://tempuri.org/:serviceList. The InnerException message was 'Enum value '0' is invalid for type 'Project.Common.DataContracts.Contract.ContractTypes' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'. Please see InnerException for more details.
Why:
You are using Windows Communication Foundation (WCF), without WCF, you will not have this issue. This is cased by a serialisation issue introduced by WCF if one of the properties in the object that you were trying to send back to the service is not defined.
Example:
Assume that the ContractType is one of the properties in ObjectType,
====ContractType.cs====
using System.Runtime.Serialization;
namespace Project.Common.DataContracts.Contract
{
[DataContract]
public enum ContractType
{
[EnumMember]
Person = 1,
[EnumMember]
Company = 2
}
}
When trying the send an instance of ObjectType back to the WCF service, all the properties of ObjectType, in this example, ContractType, should be initialized.
For example, if one of the properties in the instance is not initialized, the default value will be set to 0 (zero) if it is an enum type.
In this case, since the ContractType does not contain o (zero), and if you forget to intialize its ContractType, you will receive a similar error above.
Solution:
The solution is pretty simple, just keep a good programming habit, initialize everything before using it, and when defining the properties, the definitions should contain the fallback values, such as "null" and "0" (zero).
Rank: The world's most expensive cities to live in 2009
Currently, at least there are two rank systems that are well-known. One is from UBS and another one is from Mercer.
- About UBS: (Can read more about UBS from this article in Wikipedia)
UBS is a global financial services company, it is headquartered in Zürich, Switzerland. It is the world's largest manager of private wealth assets, "the world's biggest manager of other people's money", and is also the second-largest bank in Europe, by both market capitalisation and profitability.
- About Mercer: (Can read more from Mercer's website)
As it is claimed itself that Mercer is the global leader for trusted HR and related financial advice, products and services, Mercer has more than 18,000 employees serving clients in over 180 cities and 40 countries and territories worldwide.
The Methodologies that used to generate the ranks:
- UBS's Methodology:
USB conducted its standardized Prices and Earnings survey in 73 international cities in March 2009. The data was collected by several independent observers in each city. In all, more than 30,000 data points were included in the analysis. All amounts were converted into a single currency to ensure that the surveyed prices and earnings could be compared. To compensate for daily exchange rate fluctuations, we used the average exchange rate over the data collection period. An international price comparison needs a common, standard basket of goods and services. As in past studies, the basket of goods and services was based on Western European consumer preferences. Living costs were calculated based on a survey of 154 items in total. They include 122 products and services that are used directly to calculate the reference basket. Apartment rents were classified as high-, mid- and low-priced.
- Mercer's Methodology:
Mercer's Cost of Living survey covers 143 cities across six continents and measures the comparative cost of over 200 items in each location, including housing, transport, food, clothing, household goods and entertainment. It is the world’s most comprehensive cost of living survey and is used to help multinational companies and governments determine compensation allowance for their expatriate employees.
In Mercer’s survey, New York is used as the base city for the index and scores 100 points, all cities are compared against New York and currency movements are measured against the US dollar. Tokyo scores 143.7 points and is nearly three times as costly as Johannesburg with an index score of 49.6.
The period from March 2008 to March 2009 has been characterised by an unprecedented economic downturn. The global economic crisis has had a direct impact on the Cost of Living indices in the various locations covered by Mercer, and hence on the resulting Cost of Living rankings.
Ranks in 2009:
- UBS's rank:
2009 2008 Cities 1 2 Oslo 2 6 Zurich 3 4 Copenhagen 4 7 Geneva 5 8 Tokyo 6 5 New York 7 9 Helsinki 8 13 Vienna 9 10 Paris 10 3 Dublin 11 15 Munich 12 40 Caracas 13 16 Frankfurt 14 11 Luxembourg 15 21 Los Angeles 16 12 Stockholm 17 23 Rome 18 28 Lyon 19 34 Dubai 20 19 Brussels 21 1 London 22 26 Barcelona 23 14 Amsterdam 24 38 Singapore 25 18 Chicago 26 22 Madrid 27 30 Berlin 28 35 Hong Kong 29 33 Miami 30 20 Milan 31 24 Toronto 32 25 Montreal 33 43 Tel Aviv 34 29 Istanbul 35 32 Lisbon 36 39 Athens 37 27 Nicosia 38 17 Sydney 39 - Doha 40 47 Ljubljana 41 67 Shanghai 42 42 São Paulo 43 31 Seoul 44 51 Riga 45 36 Auckland 46 49 Taipei 47 52 Manama 48 41 Rio de Janeiro 49 54 Bratislava 50 61 Bangkok 51 50 Prague 52 65 Beijing 53 45 Tallinn 54 59 Vilnius 55 44 Warsaw 56 37 Moscow 57 46 Budapest 58 55 Sofia 59 60 Kiev 60 69 Lima 61 70 Buenos Aires 62 48 Santiago 63 62 Nairobi 64 64 Johannesburg 65 63 Jakarta 66 57 Bogotá 67 53 Bucharest 68 58 Mexico City 69 - Cairo 70 71 Kuala Lumpur 71 66 Manila 72 68 Delhi 73 56 Mumbai
- Mercer's rank:
2009 2008 Cities 1 2 Tokyo 2 11 Osaka 3 1 Moscow 4 8 Geneva 5 6 Hong Kong 6 9 Zurich 7 7 Copenhagen 8 22 New York City 9 20 Beijing 10 13 Singapore 11 10 Milan 12 24 Shangai 13 12 Paris 14 4 Oslo 15 89 Caracas 16 3 London 17 14 Tel Aviv 18 16 Rome 19 21 Helsinki 20 52 Dubai 21 19 Vienna 22 61 Shenzhen 23 55 Los Angeles 23 70 Guangzhou 25 16 Dublin 26 65 Abu Dhabi 27 34 Douala 28 25 Athens 29 25 Amsterdam 30 45 Bratislava 31 89 White Plains 32 30 Lagos 33 74 Tehran 34 51 Abidjan 34 41 Dakar 34 78 San Francisco 37 28 Madrid 38 43 Luxembourg 38 31 Barcelona 40 57 Algiers 41 77 Honolulu 41 39 Brussels 41 80 Beirut 44 44 Almaty 45 75 Miami 46 18 St Petersbourg 47 37 Munich 48 40 Frankfurt 49 38 Berlin 50 84 Chicago
Visual Studio Just In Time Debugger
I was suffering this "Visual Studio Just-In-Time Debugger" for more than a week. Everytime when I close the browser, a window like this pops up, it is so annoying.
I googled this morning and found a solution. Up to now, no pop-ups any more. It seems working fine for my machine, at least.

Here is the reslolution:
1. Open the CMD window, and run this command at the command line:
drwtsn32 -i
After that, you got a pop up window saying that: Dr.Watson has been installed as the default application debugger
2. Then run this command in the command line:
regedit
You will see an application called Registry Editor is opened.
If you are using the 32Bit Windows operating system, you should delete the follow registry keys
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger
If you are using 64Bit windows operating system, you should delete the following registry keys:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\DbgManagedDebugger
How to access controls in Master Page / Strongly typed Master Page
It is very simple for a page to access the controls in its Master Page.
For example, we can use this way:
((Label)(Master.FindControl(“LblTitle”))).Text = “My Application”;
or
(Master.FindControl(“LblTitle”) as Label).Text = “My Application”;
Can you see that? first, it is not very clean look, second, no intellisence for the LblTitle (the control ID). I don’t like this way of accessing the controls in the Master Page.
I would rather to make the Master Page strongly typed, and create properties or method in the Master Page.
In order to make the Master Page strongly typed, we need to declare the MasterType in the Aspx pages. For example:
<%@ MasterType virtualpath="~/MasterPages/Support.Master" %>