Friday, March 28, 2008
#
Are you tired of placing multiple Validation controls on Form? If you are bored of following scenario like me, keep on reading the post:
A simple Email address validation can consist of whether
- The field is empty
- Longer than limit
- Email address format is invalid
- Already in use
Ordinary solution to this problem is placing multiple validation controls for a single TextBox. You can simply it by replacing all with a single Custom Validator. Our goal is to reduce amount of controls on the form to keep it simple. To do that, we would have to write code for Custom Validator that does it all. We also would like to write minimum code to validate the control without compromising manageability. Let us assume we would write the following code inside the ServerValidate of that control:
protected void cvEmailAddress_ServerValidate(object source, ServerValidateEventArgs args)
{
ValidationController.ValidateControl<ProfileValidator>(cvEmailAddress, ProfileValidator.Fields.EmailAddress.ToString(), args);
}
Let us declare a ValidationErrorResult object that contains error messages and text to display in the UI:
public sealed class ValidationErrorResult
{
public string ErrorMessage { get; set; }
public string Text { get; set; }
}
And an Attribute which would be used to tag a specific method which would be responsible for validation of particular control:
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public sealed class ValidationMethodAttribute : Attribute
{
public ValidationMethodAttribute(string fieldName)
{
this.FieldName = fieldName;
}
public string FieldName { get; private set; }
}
If you are already familiar with Attirbute based programming, I hope you know the attribute of this piece of code is in fact ValidationMethod. We will soon see how to use this. The following is the method that checks the value and make a list of ValidationErrorResult that consists of which rules got failed. Notice that the ValidationMethod attribute contains the field name of the object which determines no matter whatever your method name is, that field name helps Validation controller to find this method out for validation.
[ValidationMethod("Email")]
public static List<ValidationErrorResult> ValidateEmail(object value)
{
var email = value as string;
var results = new List<ValidationErrorResult>();
// Blank
if (string.IsNullOrEmpty(email))
results.Add(new ValidationErrorResult()
{
ErrorMessage = "You did not provide an Email Address.",
Text = "Cannot be left blank"
});
// Length 128
if (email.Length > 128)
results.Add(new ValidationErrorResult()
{
ErrorMessage = "You exceeded length limit.",
Text = "Keep it less than 129 characters"
});
// Valid Email Address
if (!Regex.IsMatch(email, "^[\\w\\.\\-]+@[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]{1,})*(\\.[a-zA-Z]{2,3}){1,2}$"))
results.Add(new ValidationErrorResult()
{
ErrorMessage = "You provided an invalid Email Address.",
Text = "Invalid Email Address"
});
// Is Already In Use
if (IsAlreadyInUse(email))
results.Add(new ValidationErrorResult()
{
ErrorMessage = "You provided an invalid Email Address.",
Text = "Invalid Email Address"
});
return results;
}
Here is the ValidationController which goes through the Validation class and looks for the method that has the attribute which validates the control's value.
public class ValidationController
{
public static List<ValidationErrorResult> Validate<T>(string fieldName, object value)
{
var results = new List<ValidationErrorResult>();
var type = typeof(T);
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
var method = methods.Single<MethodInfo>(delegate(MethodInfo m)
{
return ((ValidationMethodAttribute[])m.GetCustomAttributes(typeof(ValidationMethodAttribute), false))[0].FieldName == fieldName;
});
return (List<ValidationErrorResult>)method.Invoke(null, new object[] { value });
}
public static void ValidateControl<T>(CustomValidator validator, string fieldName, ServerValidateEventArgs args)
{
var results = Validate<T>(fieldName, args.Value);
if (!(args.IsValid = !(results.Count > 0)))
{
validator.ErrorMessage = results[0].ErrorMessage;
validator.Text = results[0].Text;
}
}
}
Sunday, March 02, 2008
#
I'm very glad to tell you that your ".NET Research" personal blog is compatible with Windows Live Writer. You can compose, format, insert photos inside your posts offline and publish when you become online totally from this client without even opening the ".NET Research" site. Let us the steps to do this assuming you have properly installed Windows Live Writer.
Step 1. Run Windows Live Writer and Weblog > Add Weblog account..
Step 2. Choose another weblog service like the following screen and click Next:
Step 3. Now type http://dotnetbd.org as your Weblog Homepage URL, enter your credential like here I used as admin:
Now Windows Live Writer will download some necessary files to work offline and will appear with a white blank screen for you to write your first post! That's it. These simple two steps will enable you to use this powerful tool to work with your ".NET Research" personal blog. Happy blogging!
Saturday, March 01, 2008
#
One of my colleagues Mehfuz Hossain developed a wonderful open source project which allows you to query Flickr photos by LINQ, also lets you insert, delete photos directly to/from Flickr. You wonder how to extend LINQ in such an amazing way? It’s easy by writing your own custom LINQ provider, which was not-so-easy until he came up with another handy open source project named LINQ Extender. He did all the expression parsing stuff to ease our pain. Now you can make your own LINQ to Anything using this so easily.
For your heads up on LINQ extenders, here he wrote an article and LINQ to Flickr, open source project is hosted at Codeplex.
Friday, February 29, 2008
#
In LINQ to SQL, the data model of a relational database is mapped to an object model expressed in the programming language of the developer. When the application runs, LINQ to SQL translates into SQL the language-integrated queries in the object model and sends them to the database for execution. When the database returns the results, LINQ to SQL translates them back to objects that you can work with in your own programming language. You may want to make a data access layer that separates the data operation from business layer like the following:
DbHelper.Insert<Student>(
new Student()
{
FirstName = “Tanzim”,
LastName = “Saqib”,
Email = “me@TanzimSaqib.com”,
Website = “http://www.TanzimSaqib.com”}, true); // Use Transaction?
To make use of such transactional generic DbHelper, you might want to write a singeton DbHelper class like the following. You might notice that the class is singleton, it’s static and the DataContext is being used is private, and only initialized using the connection string if not yet.
public static class DbHelper
{
private const string CONNECTION_CONFIG_NAME = “StudentServerConnectionString”;
private static StudentServerDataContext _StudentServerDataContext = null;
public static StudentServerDataContext GetDataContext()
{
if(_StudentServerDataContext == null)
_StudentServerDataContext = new StudentServerDataContext
(ConfigurationManager.ConnectionStrings
[CONNECTION_CONFIG_NAME].ConnectionString);
return _StudentServerDataContext;
}
public static void CleanUp()
{
_StudentServerDataContext.Dispose();
_StudentServerDataContext = null;
}
// … code edited to save space
On application wide error or on end you can dispose the context so CleanUp method is useful here. To implement an Insert method see the following. You will find I have used a TransactionScope which ensures that the transaction is taking place without any interruption. If there is really any error the scope.Complete() method never gets invoked. This is how it ensures that the code inside the TransactionScope is taking place as a transaction. It is available from .NET 2.0 framework.
public static void Insert<T>(T t, bool isTransactional) where T : class
{
if (isTransactional)
{
using (var scope = new TransactionScope())
{
Insert<T>(t);
// On any Exception, Complete() method won’t be invoked.
// So, the transaction will be automatically rollbacked.
scope.Complete();
}
}
else
Insert<T>(t);
}
public static void Insert<T>(T t) where T : class
{
using (var db = GetDataContext())
{
db.GetTable<T>().InsertOnSubmit(t);
try
{
db.SubmitChanges();
}
catch (Exception e)
{
// TODO: log Exception
throw e;
}
}
}
I did not show other methods as part of the CRUD implementation. The rest is left open for you to implement.
Tuesday, February 05, 2008
#
Web 2.0 applications are widely developed. These applications often work with third party contents, aggregate them, make various use of them and then make something useful and meaningful to the users. For the past few years, developers were also engaged with such endeavors and a lot of their websites have not addressed performance issues, thus resulting in an unpleasant experience to the users.
Performance is a vast area and great results can never be achieved by a silver bullet. This article explores some of the key performance issues that can occur while developing a Web 2.0 portal using server side multithreading and caching. It also demonstrates model driven application development using Windows Workflow Foundation.
URL: http://dotnetslackers.com/articles/aspnet/SevenWaysToDoPerformanceOptimizationOfAnASPNET35Web20Portal.aspx
Thursday, January 10, 2008
#
In one of my earlier posts, I talked about DOM element accessing in a loop but forgot to talk about a very common, yet performance issue in AJAX. We often use code like the following:
var items = []; // Suppose a very long array
for(var i=0; i<items.length; ++i)
; // Some actionsIt can be a severe performance issue if the array is so large. JavaScript is an interpreted language, so when interpreter executes code line by line, every time it checks the condition inside the loop, you end up accessing the length property every time. Where it is applicable, if the contents of the array does not need to be changed during the loop's execution, there is no necessity to access the length property every time. Take out the length in a variable and use in every iteration:
var items = []; // Suppose a very long array
var count = items.length;
for(var i=0; i<count; ++i)
; // Some actions
Tuesday, February 05, 2008
#
It's a very common bad practice. We often iterate through array, build HTML contents and keep on concatenating into certain DOM element. Every time you execute the block of code under the loop, you create the HTML markups, discover a div, access the innerHTML of a div, and for += operator you again discover the same div, access its innerHTML and concatenate it before assigning.
function pageLoad()
{
var links = ["microsoft.com", "tanzimsaqib.com", "asp.net"];
$get('divContent').innerHTML = 'The following are my favorite sites:'
for(var i=0; i<links.length; ++i)
$get('divContent').innerHTML += '<a href="http://www.' + links[i] + '">http://www.' + links[i] + '</a><br />';
}
However, as you know accessing DOM element is one the costliest operation in JavaScript. So, it's wise to concatenate all HTML contents in a string and finally assign to the DOM element. That saves a lot of hard work for the browser.
function pageLoad()
{
var links = ["microsoft.com", "tanzimsaqib.com", "asp.net"];
var content = 'The following are my favorite sites:'
for(var i=0; i<links.length; ++i)
content += '<a href="http://www.' + links[i] + '">http://www.' + links[i] + '</a><br />';
$get('divContent').innerHTML = content;
}
Thursday, January 10, 2008
#
Less use of "var" can result into wrong calculation as well as mistake in logic control. And also JavaScript interpreter finds it hard to determine the scope of the variable if var is not used. Consider the following simple JavaScript code:
function pageLoad()
{
i = 10;
loop();
alert(i); // here, i = 100
}
function loop()
{
for(i=0; i<100; ++i)
{
// Some actions
}
}
Here you see, the loop uses the variable i used before in pageLoad. So, it brings a wrong result. Unlike .NET code, in JavaScript variables can go along with the method calls. So, better not confuse the interpreter by using more "var" in your code:
function pageLoad()
{
var i = 10;
loop();
alert(i); // here, i = 10
}
function loop()
{
for(var i=0; i<100; ++i)
{
// Some actions
}
}
Friday, January 11, 2008
#
We have seen DOM caching before and function delegation is also a kind of function caching. Take a look at the following snippet:
for(var i=0; i<count; ++i)
$get('divContent').appendChild(elements[i]); As you can figure out the code is going to be something like:
var divContent = $get('divContent');
for(var i=0; i<count; ++i)
divContent.appendChild(elements[i]); That is fine, but you can also cache browser function like
appendChild. So, the ultimate optimization will be like the following:
var divContentAppendChild = $get('divContent').appendChild;
for(var i=0; i<count; ++i)
divContentAppendChild(elements[i]);
Saturday, January 12, 2008
#
Take a look at the following loop. This loop calls a function in each iteration and the function does some stuffs. Can you think of any performance improvement idea?
for(var i=0; i<count; ++i)
processElement(elements[i]);
Well, for sufficiently large array, function delegates may result in significant performance improvement to the loop.
var delegate = processElement;
for(var i=0; i<count; ++i)
delegate(elements[i]);
The reason behind performance improvement is, JavaScript interpreter will use the function as local variable and will not lookup in its scope chain for the function body in each iteration.
Tuesday, January 15, 2008
#
Don't you think the following block of code has written keeping every possible good practice in mind? Any option for performance improvement?
function pageLoad()
{
var stringArray = new Array();
// Suppose there're a lot of strings in the array like:
stringArray.push('<div>');
stringArray.push('some content');
stringArray.push('</div>');
// ... code edited to save space
var veryLongHtml = $get('divContent').innerHTML;
var count = stringArray.length;
for(var i=0; i<count; ++i)
veryLongHtml += stringArray[i];
}
Well, as you see the innerHTML of the div has been cached so that browser will not have to access the DOM every time while iterating through stringArray, thus costlier DOM methods are being avoided. But, inside the body of the loop the JavaScript interpreter has to perform the following operation:
veryLongHtml = veryLongHtml + stringArray[i];
And the veryLongHtml contains quite a large string which means in this operation the interpreter will have to retrieve the large string and then concatenate with the stringArray elements in every iteration. One very short yet efficient solution to this problem is using join method of the array like the following, instead of looping through the array:
veryLongHtml = stringArray.join('');
However, this is very efficient than the one we were doing, since it joins the array with smaller strings which requires less memory.
Tuesday, January 29, 2008
#
I know there are GetById, GetById<> methods in Document object. But, I often miss a method that I feel should be in Volta, which iterates through its child nodes and find an element for me. Let us say, there is a HTML like the following:
<div id="divContainer">
<b>Some text</b>
<div id="firstDiv">
<i>Some more text</i>
</div>
<div id="secondDiv">
Okay, I gotta go now
</div>
<div anyAttribute="anyValue">
Babye
</div>
</div>The most important thing is, I can not get the last div by Document.
GetById, because instead of id I chose
anyAttribute. So, I wrote my own extension method which can run into not only Div but also any
HtmlElement, and can find me the desired
HtmlElement inside the prior one with the
anyAttribute and
anyValue. To make my intention clear, I'd like to show how I'd like to use that extension method:
var divContainer = Document.GetById<Div>("divContainer");
var anyDiv = divContainer.Find<Div>("anyAttribute", "anyValue");
if(anyDiv != null)
anyDiv.InnerHtml += "guys!";So, I'd like to call my extension method
Find<> which will take the type I'm looking for (in this case a Div) and that
HtmlElement should have an attribute "
anyAttribute" that contains "
anyValue". Here is how I make up the extension method:
public static class HtmlExtensions
{
public static T Find<T>(this T parent, string attribute, string value)
where T : HtmlElement
{
var element = parent.FirstChild;
while(element != null)
if (element.IsProper<T>(attribute, value))
return element as T;
else
element = element.NextSibling;
return null;
}
public static bool IsProper<T>(this DomNode element, string attribute, string value)
where T : HtmlElement
{
if (element.GetType() == typeof(T) &&
element.Attributes != null &&
element.Attributes.GetNamedItem(attribute) != null &&
element.Attributes.GetNamedItem(attribute).Value == value)
return true;
return false;
}
}This method can iterate only one depth. Multi depth implementation can be done by running a simple DFS which is left to you guys. Note one thing, I have called one extension method "
IsProper" inside another extension method, and there is no harm in it. So, this is how you can add your own extension methods to the
HtmlElement.
Sunday, January 27, 2008
#
Sunday, January 06, 2008
#
It's not pretty common. But, if you ever encounter such code, be sure it's a very bad practice. Introducing more scopes is a performance issue for JavaScript interpreter. It adds a new scope in the ladder. See the following sample scope:
function pageLoad()
{
scope1();
function scope1()
{
alert('scope1');
scope2();
function scope2()
{
alert('scope2');
}
}
}
Introducing more scopes enforces the interpreter to go through new more sections in the scope chain that it maintains for code execution. So, unnecessary scopes reduce performance and it's a bad design too.
Thursday, January 10, 2008
#
Unlike .NET languages or any other compiler languages, JavaScript interpreter can not optimize switch block. Especially when switch statement is used with different types of data, it's a heavy operation for the browser due to conversion operations occur in consequences, it's an elegant way of decision branching though.
Sunday, January 27, 2008
#
While we develop AJAX applications, we often carelessly ignore giving up bad practices, which cause effects which are not so significantly visible when the site is not so large in volume. But, it’s often severe performance issue when it is the case for sites that make heavy use of AJAX technologies such as Pageflakes, NetVibes etc.
There are so many AJAX widgets in one page that little memory leak issues combined may even result the site crash into very nasty “Operation aborted”. There are a lot of WebService calls, lot of iterations among collection so that inefficient coding in a whole lead to make site very heavy, browser eats up a lot of memory, requires very costly CPU cycles, and ultimately causes unsatisfactory user experience. In this article many of such issues are demonstrated in the context of ASP.NET AJAX.
http://www.codeproject.com/KB/ajax/AspNetAjaxBestPractices.aspx
Tuesday, January 08, 2008
#
Make minimum use of setters and getters if possible. Such accessors look like .NET like kind of beautiful properties, but these create new more scopes for JavaScript interpreter to deal with. If applicable, try directly setting/getting the private variable itself rather implementing methods for getters, setters.
Sunday, January 06, 2008
#
Avoid implementing your own getElementById method that will cause script to DOM marshalling overhead. Each time you traverse the DOM and look for certain HTML element requires the JavaScript interpreter to marshalling script to DOM. It's always better to use getElementById of document object. So, before you write a function, make sure similar functionality can be achieved from some other built-in functions.
Friday, January 25, 2008
#
HttpRequestFactory was designed for use by tiersplitting internally and was not supposed to be exposed as part of the Volta API as Danny van Velzen from Microsoft Volta team told me today. So, its better if you use XMLHttpRequest instead because this factory class might not show up in the later releases. You will find this class in Microsoft.LiveLabs.Volta.Xml namespace. As like as JavaScript's one, in this .NET version you can also Open URL, specify method name, and of course pass credentials. You can track response text, xml, status code, status text and also you can abort.
To retrieve your content, you must subscribe to ReadyStateChange event with a HtmlEventHandler which you can find in Microsoft.LiveLabs.Volta.Html namespace and check the status code. If it is 200 that means "HTTP OK", you can take the ResponseText or ResponseXML. See this example:
string content = string.Empty;
var request = new XMLHttpRequest();
request.ReadyStateChange += delegate()
{
if (request.Status == 200)
content = request1.ResponseText;
};
request.Open("POST", "http://tanzimsaqib.com/feed/", true);However, you cannot fetch cross domain content by XMLHttpRequest. The Volta compiler creates client side JavaScript XMLHttpRequest and lets developers write code in .NET friendly way. So, I do not think there is any way to retrieve cross domain content in Volta, and leaving us on the same old HttpRequest class.
Sunday, January 20, 2008
#
I have just configured my GeeksWithBlogs.net blog in Windows Live Writer. Steps are simple:
1. Put your blog URL. E.g. http://geekswithblogs.net/saqib, and User, Password
2. Choose “Another blog service”
3. Put an URL like (in my case): http://geekswithblogs.net/saqib/services/MetaBlogAPI.aspx
Friday, January 18, 2008
#
Someone had questions about the article recent I wrote on DotNetSlackers are:
“i am curious to know how you have hooked the DownloadPhotos to voltaControl1, is it hooked automatically, when added to the volta project, what is the case of using external flickr api ? Also, let me know what is the purpose of screen_name in voltaControl1.”
You might have the same questions, so to clarify, here are the answers:
Inside VoltaControl, PhotosLoaded event of FlickrHelper class is subscribed and FlickrHelper's DownloadPhotos is invoked so that as soon as the photo data is finished downloading, the subscriber (VoltaControl) is notified with the photo data, to manipulate the UI. Such events are not automatic, these are manually created inside FlickrHelper class.
If you'd like to use external Flickr API, you need to change the way how it works now. It's been designed to make a tiny widget with simple and least functionalities in order to demonstrate making of a Volta control.
screen_name is your Flickr account's screen name which is a required parameter to retrieve the "NSID" of your account which is necessary to build URLs to your photos.
This is my first article which is based on the first CTP of Volta considering its current limitations. You will see how you can create a Volta control that the compiler can convert into an AJAX Widget without requiring us writing a single line of JavaScript code: http://dotnetslackers.com/articles/aspnet/BuildingAVoltaControlAFlickrWidget.aspx
Thursday, January 03, 2008
#
When a Volta control is rendered, the ID attribute of the generated HTML is changed to something like _vcId_1_DivName which is inconvenient to find from code. But the ID attribute stays the same in case of Volta Page, so it is discoverable by ID like this:
Div divContent = Document.GetById<Div>("divContent");
However, if you add HTML controls to the control like the following, the ID is not changed during the rendering:
public VoltaControl1() : base("VoltaControl1.html")
{
InitializeComponent();
Button btnClick = new Button();
btnClick.InnerText = "Click!";
btnClick.Id = "btnClick";
this.Add(btnClick);
}
If you don't prefer this way and seriously want to write your own HTML in the control's html page, you might find the following snippet useful. But, remember in this case you will use name attribute of the html element instead of ID.
// Usage: var element = GetElementByName(Document.GetElementsByTagName("div"), "divWidget");
private HtmlElement GetElementByName(HtmlElementCollection elements, string name)
{
foreach (var element in elements)
{
DomAttribute nameAttribute = element.Attributes.GetNamedItem("name");
if (nameAttribute != null)
if (nameAttribute.Value == name)
return element;
}
return null;
}
Wednesday, January 02, 2008
#
Making a cross domain AJAX call in Volta is piece of cake. Volta compiler generates necessary client codes to make it work. Here is a snippet that can make an AJAX call to some Url and fetch data:
public void DownloadPhotos()
{
IHttpRequest request = HttpRequestFactory.Create();
request.AsyncSend("POST", URL, string.Empty,
delegate(string response)
{
OnPhotosLoaded(new PhotosLoadedEventArgs(response));
});
}
Both IHttpRequest and HttpRequestFactory classes can be found in the Microsoft.LiveLabs.Volta.MultiTier namespace. AsyncSend method performs the asynchronous call and calls back the delegate defined where OnPhotosLoaded event is fired to notify the subscriber of this event that the data has just arrived.
Monday, January 14, 2008
#
It's still long way to go for a final release of ASP.NET MVC, the one I've been using right now is just a December CTP. But, like me you might be experiencing this confusing problem. The server controls that you put in a View (ViewContentPage) can not be found in code-behind page. The reason behind it is - the Views don't have a back-end designer code file. I believe it's just a bug or they could not find time to fix/look into it. I'm sure it will be fixed in any of the upcoming versions.
To enable this, switch to Solution Explorer, right click on the View you are interested in, and choose Convert to Web Application. Now, you will find the server controls in code-behind file.