Wednesday, October 28, 2009
to download the source code please click here
The <iframe> tag defines an inline frame that contains another document and is supported in all major browsers.

The <iframe> can be placed anywhere in the document flow. The iframe properties such as height and width can be easily modified by CSS and JavaScript. Data can be passed back and forth between the parent container and iframe using Javasrcipt. The document that is displayed inside an iframe can access the main window by the parent keyword. Iframe can have their own source URL that is distinct from the parent page and we are interested on this feature. We first declare an Iframe in the page and keep it hidden. We then point the Iframe to our preferred web handler, during page load iframe initiate a request to the server and the server start the lengthy task, and flushes state change information. The server flushes the response wrapped inside <script> tag to perform DOM manipulation on the parent container – similar technique that we have seen in one of my post earlier. Here are the steps to follow.
- Declare Iframe in the page.
- Hide the Iframe.
- Point the src of the Iframe to the web handler.
- Get Iframe to initiate request from the the browser client to the web server when the page loads.
- Get the web handler to flush response on task state changes.
- Perform DOM manipulation on the parent container.

Here I have declared two javascript functions in the parent page – “updateContent” and “hide”. “UpdateContent” replaces the data on “ReportDiv” element. “Hide” hides the loader image when lengthy task ends. Then down below on the same page I have declared the iframe tag, pointed the src of the iframe to a regular web handler “JsWrappedDataHandler.ashx”, and used the style elements to hide the iframe. Lets look at the web handler and what is cooking there.
This is a regular web handler and you may be wondering why am I sending 256 dummy bytes. This is a workaround to make IE work properly because IE accepts a message from the server after the first 256 bytes. This technique is handy when we do not know about the message size and we can avoid any unexpected event by sending 256 dummy bytes before sending the original message. Next thing to look at is the script block – where it invokes the javascript functions that we defined in the parent container. Example window.paren.updateContent(data), window.paren.hide(). Finally the server is flushes the response directly to the browser. The Iframe receives the progressive flushed response chunk/script block and executes the javascript code - which invokes the javascript functions from of the parent container and updates the content of of “ReportDiv” element until the task completes. The end user gets immediate feedback on task state changes and do not need to wait until the entire response download. When the task is complete it invokes the hide() function to hide the loader image. This is what it looks like.
Asynchronous web handlers
I discussed a little bit about asynchronous web handlers in earlier post and I promised that I will talk about it later – so I do so. It is recommended to use asynchronous web handlers for long/ lengthy tasks. An asyncchronous web handler implements IHttpAsyncHanddler – this means it implements two additional methods BeginProcessRequest and EndProcessRequest. The idea here is to spawn custom threads by hand to run the lengthy portion of the task and not block important ASP.NET work threads from the threadpool. I have discussed about why we should spawn an additional thread in great length in this post, and I am not going to go through that again here, I am jumping straight in to the implentation of Asynchronous web handler.
This page is exactly same as the first one in this post where I declared 2 javascript function in the parent container such as “undateContent” and “hide”. The only difference is the iframe is now pointing to a different web handler and this time an asynchronous handler.
Here this asynchronous web handler implements the IHttpAsyncHandler. The BeginProcessRequest performs all the lengthy bits inside request.BeginProcessRequest method asynchronously and signals when the task is completed. This executes the EndProcessRequest method. The AsycWebHandlerRequest class is a custom hand written class and I paste the code below.
Here I spawn custom Threads by hand to invoke the LongTask method. Long task has exact same code as we have seen in the regular web handler ProcessRequest method above, except the last line where it signals that the task is complete by invoking requestState.CompleteRequest method. Here the Response.Flush method does all the hard work to notify the connected browser about the task state changes and end user can enjoy immediate feedback from the server. You may be wondering about the AsyncRequestState class. I have used the exact same class during implementation of the Asynchrounous Page and can be found here.
I have indicated earlier that a web handlers is recommended for performance critical web pages. I have done some load tests to compare the result of regular web handler, asynchronous web handler and the asynchronous page that pretty much does the exact same operation. The test result of load tests that I have performed in exact same environment can be found below.
Fig: Load test of Iframe and asychronous web handler that uses custom thread
Fig: Load test of Iframe and regular web handler
Fig: Load test of asynchronous web page that implements custom thread
You can see that the asynchronous web handler that spawns custom thread is the clear winner. And when you compare Asynchronous page with web handler – we see web handler is superior.
Please note that the different techniques that I have been discussing in last several posts is also known as Comet that describe the web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser expicitly requesting it. However holding a connection open for infinite period has negative impact on browser usability. The problem is the javascript will keep accumulating and the page will have to preserve them in the page itself, resulting in a unbound page size and memory implications – at worst the page becomes totally unresponsive and will crash the browser. These is ok to choose for long task that has a definite end, however we need to be a bit careful when it comes to a “real-time” applications that keeps running for indefinite period. For example an airlines time table,
For a “real-time” application ( i.e. chat application, airline timetable ) a polling / long polling mechanism is more suitable where the server keeps looping for infinite period - produces the latest content and store it in a persistent layer – example a database/file, or in the application memory. The browser polls the latest response periodically, performs DOM manipulation to updates the page – and the user gets to see the latest record. Lets look at the polling techniques in my next post.
XMLHttpRequest (XHR) is a DOM API that can be used inside a web browser scripting language, such as JavaScript, to send an HTTP or an HTTPS request directly to a web server and load the server response data directly back into the scripting language. The technique that we are going to discuss here takes advantage of XMLHttpRequest objects readyState == 3 status (Interactive – Downloading) and responseText property to perform DOM manipulation in a browser. Here is how it works
- A request is initiated from the the browser client to the web server using the XMLHttpRequest object.
- The webserver flushes response during task state changes.
- XMLHttpRequest object holds partial data in responseText property when readyState is 3 ( Interactive – Downloading ).
- DOM manipulation is perfomed during readystate == 3 to interactively update the web content.
to download the source code please click here
Please note that XMLHttpRequest based technique will not work in all browsers. Microsoft clearly mentions in the specification that - “readyState = 3, some data has been received. responseText is not available. responseBody is not available.” So this will not work in IE. However I found it working in Firefox and Chrome. Here is the code.
Here I have created a XmlHttpRequest object and configured it to perform a GET request to my DataHandler.ashx that I have created earlier. The piece of code that does the magic to notify the browser on state changes is the part where I am updating the content of “ReportDiv” element with req.responseText when req.readyState == 3. The responseText dynamically loads the flushed response and this piece of code updates the content of the browser. Then finally I hide the loader image when the req.readyState turns 4 that means – loaded, all the data has been received. This entire process is initiated by the getData() method which is invoked during the pageload even, but you can do the same on onclick of a button or anchor tag or by raising some other event that suits your need. For a refresher on what is happening inside DataHandler.ashx here is the web handler codes.
The web handler simulates a long running task by putting the Thread to sleep. However it keeps flushing the response when the browser is connected to the server, until the task is complete. Please check my earlier post where I have done detailed discussion on Response.IsClientConnected property, Response.Flush method etc.
You may be wondering that this is still not the perfect solution that we are looking for as responseText is not available during readyState==3 in all browsers, we cannot do much about this however we can implement the IFrame Call that works in most of the browsers. Lets look at that.
It is quite common to display a loader-image or some kind of progress bar image in a browser when the server is busy serving the request. Before we go deep into page streaming techniques with XMLHTTPRequest call and IFrame, lets look into a simple loader icon implementation – the idea is to display “loading” image until the task completes, display the response in the browser when task ends and hide the loader image.
to download the source code please click here
Invoke a long task and display loader image to notify task progress – using MS AJAX
Normally in a ASP.NET page we drop the ScriptManager control, put a reference of the webservice that we want to point to. The Scriptmanager goes and creates necessary proxy class for the webmethods. We can also add static methods to an ASP.NET page and qualify them as web methods and invoke them using javascript. This tutorial shows how to do all these by configuring the ScriptManager easily. However I will play with the Sys.Net.WebRequest class directly here. The Sys.Net.WebRequest provides the script API to make Web request. It becomes handy when we need to partially update a little section of the page and it is quite straight forward to use the Web Request class anyway.
It may look like a lots of code above but when you look closely you find that all I have done is setup a get request to asynchronously invoke my DataHandler.ashx web handler that I created earlier. During page load the “PageLoad” method is called and this initiates the entire process. You can also do the same on the onclick event of an input button or anchor tag or by raising some other events that you prefer. The image that I used for the loader has been generated from this website Ajaxload.info, this website has some nice loader image designs available. You can choose your indicator, background color, foreground color and generate your preferred loader. The webrequest invokes the web handler and the loader image is displayed until the full response is available. I populate the “ReportDiv” element with the completed response data, and hide the loader image with loader.style.display = “none”. There is also some codes above that handles timeout and abort situations.
Invoke a long task and display loader image to notify task progress – using JQuery
The JQuery based implementation of the same above is even more simpler and is done with a lot less coding.
All I do here is I configure HTTP GET request call to my DataHandler.ashx inside the “$(document).ready” function -this function is infact the first thing to learn about jQuery if you are new to JQuery. If you want an event to work on your page, you should call it inside the $(document).ready() function. Everything inside it will load as soon as the DOM is loaded and before the page contents are loaded. If you have not worked with JQuery yet I would strongly recommend to have a look at it. The getData() function makes the HTTP GET call to the web handler and on success I put the response to the “ReportDiv” element. Then I hide the loader icon with style display = “none”;
Thats pretty much it, however this is not a robust solution and I am writing all the post in this series to render realtime states of a task in the browser. When we use this technique all we can display is the loader image to notify users that server is busy processing his/her request – we cannot display any real time update on the tasks state changes to the browser. The MS AJAX and JQuery web request calls do not allow to check XMLHttpRequest s readyState==3 status (will discuss about XMLHttpRequest object in the next post ). The web applications are stateless and request can only be initiated from the client, however XMLHttpRequest or a IFrame call can initiate a parallel request to the server and we can take advantage of that to stream contents to the browser. Lets look at them.
to download the source code please click here
In the earlier post we have discussed little bit about the limited number of worker threads available in the thread pool of ASP.NET and we identified why we should always try to avoid to block those important worker threads. ASP.NET 2.0 introduces Asyn=”true” attribute in the page to handle asynchronous scenarios and under the hood this attribute tells ASP.NET to implement IHttpAsyncHandler in the page. There are more than one ways available in ASP.NET 2.0 and ASP.NET 2.0 (plus) to register asynchronous tasks in the page,
- by AddOnPreRenderCompleteAsync method.
- by declaring PageAsynTask tasks and register them by RegisterAsyncTask method.
However PageAsyncTask provides some extra flexibility over AddOnPreRenderCompleteAsync method, for example
- it offers a timeout option.
- allows to register more than one async task.
- allows to configure async tasks to be executed in parallel or sequentially
- RegisterAsyncTask passes HttpContext.Current to the End and Timeout methods
- RegisterAsyncTask allows to pass object state to the Begin methods.
Lets look at how we can implement an asynchronous page to serve our scenario that we are focusing here, that is, to run long tasks asynchronously and at the same time provide immediate feedback to the browser.
Fig: aspx page
Fig: code behind
Here in the above code block I have left the AddOnPreRenderCompleteAsync code commented which can be used alternative to PageAsyncTask object & RegisterAsyncTask method. I have registered a PageAsyncTask task using RegisterAsyncTask method. The “task” object is configured to point to – BeginAsyncOperation, EndAsyncOperation and TimeoutAsyncOperation functions. The BeginAsyncOperation does all the lengthy bits inside request.BeginProcessRequest() method and signals when completed, this executes the EndAsyncOperation method. However if the lengthy task is not completed within the timeout period, the TimeoutAsyncOperation executes. Lets look at the AsyncRequest class now.
The most important thing to note here in the above piece of code is, I spawn an additional custom thread by hand and I execute the lengthy bits i.e. the “Process” Method in the custom thread. The Process method simulates the lengthy task by putting the thread to sleep. However note that the Response.Flush() does the magic to notify the connected browser about the task state immediately. It is a good idea to always check the Response.IsClientConnected property we discussed this in length in one of our earlier post.
As soon as the lengthy task completes I call the CompleteRequest method of the requestState object.
The CompleteRequest singnals that the asynchronous task is complete and it invokes the the callback method if available. In this example the callback invokes EndAsyncOperation method that we have configured in our PageAsyncTask object.
You may be wondering why I had to spawn a custom thread to run the lengthy operation where we can simply use asynchronous delegate invocation. You must know that Delegate.Invoke consumes worker thread from the ASP.NET thread pool. Even though the page releases a worker thread into the pool but immediately that thread ( or another worker thread ) is again taken from the thread pool. Now this precious thread is occupied until the long task finishes hence you gain nothing rather add overhead of switching thread from the pool.
Fritz Onion in his popular article “Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code” mentioned the same, “Asynchronous delegate invocation completely defeats the purpose of building an asynchronous handler because it draws from the same process-wide CLR thread pool that ASP.NET uses to service requests. While the primary request thread is indeed returned to the thread pool, another thread is taken out to perform the asynchronous delegate execution, which means that there is a net gain of zero threads for servicing additional requests, rendering the handler useless. You will run into the same problem if you use ThreadPool.QueueUserWorkItem to perform the asynchronous request processing because it also draws threads from the same process-wide CLR thread pool”.
Jeff Prosise also quoted him in his article by saying “Asynchronous delegates, are counterproductive in ASP.NET applications because they either steal threads from the thread pool or risk unconstrained thread growth. A proper asynchronous page implementation uses a custom thread pool, and custom thread pool classes are not trivial to write.”
He also warned about it in his conclusion “A final point to keep in mind as you build asynchronous pages is that you should not launch asynchronous operations that borrow from the same thread pool that ASP.NET uses. For example, calling ThreadPool.QueueUserWorkItem at a page's asynchronous point is counterproductive because that method draws from the thread pool, resulting in a net gain of zero threads for processing requests”.
After all these warnings if you were still implementing the frequently recommended asynchronous delegation invocation ( unfortunately, most of the google search result on this topic of asynchronous programming in ASP.NET will lead to an implementation of asynchronous delegation ) it would look something like this:
I do not want to discuss about delegate invocation because it completely defeats the purpose of implementing Asynchronous pages. I have done some load testing on the above two implementations and found the following result:
Fig: Load test result of asynchronous handlers with a delegate.
Fig: Load test result of asynchronous handler with custom thread.
Clearly we see that we gain significantly on asynchronous handler that uses custom thread in both cases,
- requests/sec_total and
- avg. Respons_Total.
I got distracted a bit from our original subject matter again, but it was worth doing this one. I have already discussed here how we can run long running task asynchronously and how to provide immediate feedback to the connected browser immediately. In this post and previous posts I was implementing solutions by taking advantage of ASP.NET page and web handlers however we can also give immediate feedback to clients using MS AJAX, JQuery, XMLHTTPRequest, IFrame etc. in ASP.NET pages. Lets look at them one by one.
Here in this series of post I am discussing few techniques to give client instant feedback on task progress in ASP.NET page. In the previous post I have discussed about displaying task progress - using regular handler, here I will discuss how to do the same in standard asp.net page.
to download the source code please click here
Display task progress – in standard asp.net page
In this technique we write some regular ASP.NET script in the page itself, that performs streaming to the original page response directly. We put the lengthy task related code in the page and keep flushing the response when task state changes. The data is pushed to the the pages outgoing stream and the browser immediately displays the output. The connection to the browser is kept open until the task is complete.

You see above I have written a regular ASP.NET page with some C# scripts that simulated a long running task by forcing the thread to sleep. However before the thread goes to sleep it Flushes the response using Response.Flush method. I discussed about the Flush method in earlier post. It basically facilitates to send buffered output to the browser immediately. The other thing to note here is the the Response.IsClientConnected property which indicates the server whether the browser is still connected or not. The Response.IsClientConnected property can determine if the browser is still connected. So when we perform a lengthy operation it is a good idea to periodically test whether the browser is still connected.
You may have already noticed that I am writing embedded javascript codes that manipulates the DOM. In this case this the ReportDiv elements innerHTML is assigned to latest flushed response. However to keep this example simple, I have been flushing the “report” string over and over again to reflect the changes in the browser and the same data is sent across the wire over and over. This may not be a good idea when you are flushing out a large report with 1000 records. You can reduce the amount of response traffic just by sending the progressive latest content only. To do this you will need to change your DOM manipulation code to perform append instead of replacement. Something like below.
Note that I have changed the codes to flush progressing latest content only, I have also modified the rendered javascript codes that is now appending latest flushed content to the existing content instead of replacement.
The above example is serving the long task in a regular synchronous manner however It is a good idea to implement long running tasks asynchronously, lets look at that in the next post.
As an ASP.NET developer we frequently deal with long running tasks for example:
- Making long-lasting webservice calls.
- Making prolonged calls to database that runs complex queries.
- Do lengthy file operation
- Calling remote objects etc.
When the server is busy performing the lengthy time consuming task/tasks, the poor user has to wait for the response. The most common technique used to interact with user is to display a loader icon or show some kind of progress bar on the page until the task is complete. However we can provide user immediate feedback of the task progress/state while the task is running in the Server and make the page more interactive/informative.
Here we will discuss several techniques to give end user instant feedback on the browser about task progress in ASP.NET pages.
such as display:
Display task progress using regular web handler:
This is very easy to code, all we need to do is write a regular web handler that runs the long running task and we have to keep flushing the response when state changes, in other words we decide to flush when the task reaches certain stage. The data is pushed to the the outgoing stream and the browser immediately displays the output. The connection to the browser is kept open until the task is complete.
We have created a regular web handler that inherits from IHttpHandler and simulated a long running task by forcing the thread to sleep. However before the thread goes to sleep it Flushes the response using Response.Flush() method. The Flush method sends buffered output immediately. Normally all of the response is sent to the browser only when page completes its processing. This may be a issue for a long running task as the end user will not see anything until the page is complete. The Flush method comes handy in this situation and can send buffered output periodically to the browser. Imagine you will have to display 500 records and you can flush the buffer every 20 records until it is complete. The good thing of doing this is – user can see some data immediately, visualize the progress of the report and the server memory is also released on every Flush operation.
One more thing to note is the Response.IsClientConnected property which indicates the server whether the browser is still connected or has already left. A very common scenario is user starts the long expensive task but decided to close the browser before the task is complete. When a browser requests the page from the server but does not wait for the entire page to be downloaded, the server continues to process the request, wasting CPU cycles. The Response.IsClientConnected property can determine if the browser is still connected or not. So when we perform a long task it is always a good idea to periodically test whether the browser is still connected or not.
A web handler file works just like a aspx page and can be directly browsed via a browser. The web handler above, returns response type text/html and we have pointed an anchor tag to the web handler. Please note a web handler is recommended for a performance critical web page.
I have started with a regular synchronous web handler, however it is recommended to use asynchronous web handlers that implements IHttpAsyncHandler for long running tasks. ASP.NET has limited number of threads in the thread pool and a normal synchronous page holds on to the thread for the duration of the request, and this thread is prevented to be used to process any other request during that period. As a result the thread gets stuck until the lengthy request is complete. If all the threads are stuck doing lengthy tasks the subsequent additional requests starts to queue up and when the queue fill up ASP.NET starts spitting 503 “Server Unavailable” errors.
ASP.NET provides a neater solution to this problem via Asynchrounous web handlers that implements the IHtttpAsyncHandler. The interface suggests to implement two additional methods BeginProcessRequest method and EndProcessRequest. The idea is to spawn an additional thread by hand in response to BeginProcessRequest, then perform the lengthy task in this additional thread and notify when the task is complete so the worker thread can return a response to the user. We will look at Asynchronous web handlers in a later post in more details. Lets continue to look at other techniques now.
Friday, September 25, 2009
Now help is on the way in the form of Microsoft WebsiteSpark, a program announced today that will empower Web site design and Web application development firms with 10 or fewer employees. WebsiteSpark provides development tools, production licenses for server products, technical support, business development support, and access to the expertise and services of Microsoft’s community of partners and hosters.
visit http://www.microsoft.com/web/websitespark to learn more.
Sunday, August 23, 2009
In my previous blog post, I have discussed about how to get asynchronous JQuery treevew to work with ASP.NET Webservices, and we identified that, to make a successful ASP.NET webservice call using JQuery the request must be POST request, the content type of the request must be “application/json; charset=utf-8”, and the data parameter of the the $.ajax() method must be passed as a string. We also looked at the tweaks that we need to do to the jquery.treeview.async.js file to get that working.
However I found the JQuery, $.ajax() method can consume JSON objects straightway from the ASP.NET Generic Handler (ashx) that can be designed to serve a JSON response. If you are using ASP.NET MVC framework you will find that $.ajax() can also consume JSON response without hassle from MVC controller actions that returns a JsonResult. I will demonstrate both scenario with my FictitiousWebsite.com.
Fig: FictitiousWebsite.com
Lets look at the ASP.NET MVC Fictitious website application first,
ASP.NET MVC Application
- I have put together two classes (TreeService, TheTreeNode) that generates story categories and subcategories as seen in the screenshot above - [categories: “.NET, ASP.NET MVC, AJAX, ADO.NET”, subcategories: “Latest articles, Forum post”]. The TreeService class returns story catetories and subcategories as List<TheTreeNode>.
- Then I have designed an MVC controller action to return JsonResult. This serves the Jquery treeview control with the list of story categories and subcategories as JSON response.
I have used “d” variable here to replicate the security feature that has been added to ASP.NET 3.5 JSON serialization, you will notice the JSON response is encapsulated within a parent object to address a nasty vulnerability. You can read more about this vulnerability that Phil Haack has discussed in this post “Json Hijacking”. Encapsulating the JSON response results the following response .
- The I have created a View - “LatestStories.aspx” that hosts the JQuery treeview control.
Note that , the treeview control is communicating to my MVC controller discusssed in previous step, through this URL, “/Home/GetStoryList”. You will also notice that I have decoraded a fileClick event for the treeView. When user clicks the subcategories, it asynchronously/on demand gets the relevant list of stories from this URL “/Home/Stories” and renders to the right side panel. This fileclick event do not ship with treeview out of the box, I had to inject 2 lines of code to the original “jquery.treeview.async.js” file to get this happening.
- Finally I decorated a aspx template - “Stories.aspx” that serves the necessary html content for the right side panel.
I prefer using templates as aspx files, as I can take full advantage of the intellisense and design support of the Visual Studio. Plus I have the entire ASP.NET MVC framework to back me up to produce and render dynamic contents on demand.
It is very straight forward to consume JSON response in the ASP.NET MVC framework, however the same is not as easy when we deal with ASP.NET Webservices as discussed in my previous post. ASP.NET Webservices is not the only way we can serve JSON response, lets look at how we can design a ASP.NET Generic Handler (ashx) to serve the same. Plus you will also find in a moment that ashx can be more easily consumed by the JQuery $.ajax() method.
ASP.NET 3.5 Website
I have created an exact replica of the FictitiousWebsite.com in an ASP.NET 3.5 website project. This website project has exact same files as the ASP.NET MVC application, with very minor differences.
- Here look at the ASP.NET solution explorer snap to get a quick rundown of the similarities and the differences.
- The (TreeService.cs, TheTreeNode.cs) files are exactly same as before and generates list of story categories and subcategories.
- The ASP.NET Generic Handler (ashx) file “GetStoryListJsonHandler.ashx” serves JSON response to the Jquery treeview control with the list of story categories and subcategories.
You may already recall that we have written similar code in the MVC controller that was invoking the TreeService and returning JsonResult. I have decorated this Generic Handler (ashx) in the similar way. Note I have defined the ContentType = “application/json”, and serialized the data with JavaScriptSerializer. I have also used the “d” variable to replicate the security feature that has been added to ASP.NET 3.5 JSON serialization as before. This results exactly same output as we have seen in the MVC framework earlier. The best part is JQuery $.ajax() method can consume this without any hassle as we have faced earlier to communicate to the ASP.NET Webservice method.
- The “LatestStories.aspx” hosts the treeview control, the only difference you will note here is it now communicates with the ASP.NET Generic Handler (ashx) file, and the fileClick communicates to the “Stories.aspx” template.
- The “Stories.aspx” file (template) serves the necessary html content to display the list of stories to the right side panel. This page is now backed up by the ASP.NET web forms framework, WYSIWYG designer support in Visual Studio and allows to render dynamic contents easily.
Conclusion
We have discussed, how we can serve JSON response in both ASP.NET MVC and ASP.NET 3.5 website framework. We have identified that consuming a JSON response from ASP.NET Webservice requires some extra steps in the JQuery world, we have demonstrated an alternative approach to serve JSON response using Generic Handler (ashx) and found it easier to consume via JQuery $.ajax() method. While designing the JSON response we used “d” variable to replicate the security feature that has been added to ASP.NET 3.5 JSON serialization. We also looked at rendering dynamic content asynchronously on demand, and identified the advantage of aspx templates as it can be designed using the WYSIWYG designer, intellisense, compilation, dubug, sourceview, splitview, codebehind and all the features of Visual studio and the the ASP.NET framework.
The ficitiouswebsite.com demonstrates everything that we have discussed above and is available to
Thank you for being with me so far, Happy Coding.
Saturday, July 11, 2009
Recently I had to display some hierarchical data in a treeview. I looked around and found JQuery treeview can transforms an unordered list into an expandable and collapsable tree, and supports both location and cookie based persistence.
Fig: JQuery Treeview
As I was dealing with a large amount of data I needed something that will allow me to navigate through the data asynchronously, and I found jQuery Treeview fits well for my purpose. I found this demo of Lazy Loading Tree and I needed to implement similar functionality where the JQuety Treeview communicates to a ASP.NET Webservice.
Problem 1: Unfortunately the codes that ships with the demo do not work with ASP.NET Webservice out of the box. First of all if you have downloaded the TreeView plugin from this link http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ you will notice the "jquery.treeview.async.js" file uses $.getJSON method to make AJAX calls to the server. But this is no good for ASP.NET webservice or WCF which expect JSON POST , this function is only useful for simple JSON results returned from arbitrary services.
Problem 2: However if you download the jquery.treeview.async.js from http://view.jquery.com/trunk/plugins/treeview you will notice the $.getJSON function is commented and an alternative $ajax() method has been used.
but this one is still not good for ASP.NET Webservice calls, I am explaining this in a moment.
There are several options available in JQuery to make AJAX calls to the server. They are
1. $.ajax(opt),
2. $(sel).load(url,data,callback)
3. $.get(url,data,callback,type)
4. $.post(url,data,callback,type)
5. $.getJSON(url,data,callback)
6. $.getScript(url,callback)
The complete list of JQuery AJAX "Requests" and "Event" based functions are all listed here. However to get JQuery working with ASP.NET Webservices we should be interested with $.ajax(opt) function, a low level Ajax function which offers to create any kind of Ajax request. This allow us to configure Ajax request with a set of key/value pairs, and all options are optional. We should be aware that ASP.NET AJAX 1.0 includes a number of default settings and built-in features to prevent from JSON hijacking attacks, ASP.NET AJAX webmethods do not enable HTTP GET requests by default. To make a successful call to the ASP.NET webservice using JQuery we need to make sure that the request must be a POST request, and the request's content-type must be: "application/json; charset=utf-8. By now you have already realized that the above $.ajax() call do not fit any of these two requirements. So I attempted to fulfill these requirements and passed more option paramameters as part of the $.ajax() call.
Problem 3: I modified the script to fit the requirements
- the request must be a POST request
- the request's content-type must be: "application/json; charset=utf-8
However this did not work either. now I started facing another problem, "Invalid JSON primitive: root."
After googling on this issue for a while I found, as the data parameter is a valid JSON object, calling the webservice in this way do not throw any exception, but it also do not produce the desired result either. Instead of passing the data JSON object to the webservice, JQuery automatically serializes and sends it as root = source.
The solution is to make sure that we pass data parameter as a string instead of a JSON object. Encosia.com has a very good post on this subject "3 mistakes to avoid when using JQuery with ASP.NET AJAX", a must read. Finally I adjusted the script as follows and it started working as desired.
Conclusion
I have discussed how to get JQuery treeview working with ASP.NET Webservice. Out of the box treeview ships with "jquery.treeview.async.js" file that is not compatible with ASP.NET Webservices or WCF. To make a successful call to the ASP.NET webservice using JQuery we need to make sure
- the request must be a POST request, and
- the request's content-type must be: "application/json; charset=utf-8.
- the data parameter of the $.ajax() method must be passed as a string.
I hope this will save you some time. Thank you for being with me so far.
Tuesday, May 19, 2009
Search Engine Optimization guides, recommends to have one version of a URL of the same content. Search engines may pickup www and non-www versions of URL as 2 separate URLs, i.e. http://xyz.com/page1 may be considered different to http://www.xyz.com/page1. It is a good idea to pick on of these URLs as preferred and use 301 redirects to send traffic from the other URLS to the preferred URL. Today we will pickup www version of URL as our preferred URL and look at how we can redirect the non-www version of the URL to our preferred URL structure using ASP.NET MVC.
We can achieve the above by writing a custom handler that extends from the MvcHandler. We are basically interested in the ProcessRequest method where we can get hold of the non-www version of the URL to replace it to the www. version of URL.
public class The301GlobalHandler : MvcHandler
{
public The301GlobalHandler(RequestContext requestContext) : base(requestContext) { }
protected override void ProcessRequest(HttpContextBase httpContext)
{
//We do not want this handler to process local requests
if (httpContext.Request.IsLocal)
base.ProcessRequest(httpContext);
else
ProcessExternalRequest(httpContext);
}
private void ProcessExternalRequest(HttpContextBase httpContext)
{
bool urlChanged = false;
string url = RequestContext.HttpContext.Request.Url.AbsoluteUri;
//Check for non-www version URL
if (!RequestContext.HttpContext.Request.Url.AbsoluteUri.Contains("www"))
{
urlChanged = true;
//change to www. version URL
url = url.Replace("http://", "http://www.");
}
ProcessExternalRequest(url, urlChanged, httpContext);
}
private void ProcessExternalRequest(string url, bool urlChanged, HttpContextBase httpContext)
{
if (urlChanged)
{
//mark as 301
httpContext.Response.Status = "301 Moved Permanently";
httpContext.Response.StatusCode = 301;
httpContext.Response.AppendHeader("Location", url);
}
else
base.ProcessRequest(httpContext);
}
}
The above code is self explanatory, we are checking if the Request is local or external, we are only interested on external URLs. Next we check, whether the RequestContext.HttpCOntext.Request.Url.AbsoluteUri contains a "www" or not. If it do not contain a "www" we go and inject a "www" to the URL to convert the non-www version of URL to a www. version URL. Then we mark the previous response to a 301, which indicates that the previous URL has been permanently removed and all future requests should be directed to the given new URL.
We have developed our core handler above, however we need a wrapper IRouteHandler class to get the above The301GlobalHandler to work within the MVC Framework. This wrapper class is responsible to return an instance of the The301GlobalHandler.
public class Route301GlobalHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new The301GlobalHandler(requestContext);
}
}
We have got our Route301GlobalHandler ready, now we need all of our requests to go via this handler instead of the default. One easy way to do this, is to iterate through the route collection and assign them to this Route301GlobalHandler during the Application_Start().
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
Route301Global.ReAssignHandler(RouteTable.Routes);
}
public static class Route301Global
{
public static void ReAssignHandler(RouteCollection routes)
{
using (routes.GetReadLock())
{
AssignRoute301GlobalHandler(routes);
}
}
private static void AssignRoute301GlobalHandler(IEnumerable<RouteBase> routes)
{
foreach (var routeBase in routes)
{
AssignRoute301GlobalHandler(routeBase);
}
}
private static void AssignRoute301GlobalHandler(RouteBase routeBase)
{
var route = routeBase as Route;
if (route == null) return;
if (route.RouteHandler.GetType() != typeof(Route301Handler))
route.RouteHandler = new Route301GlobalHandler();
}
}
Note, if you have other custom RouteHandler in your application, you will need to tweak this code, I am assuming all routes that will be mapped in the RegisterRoutes(RouteCollection routes) method uses the MvcHandler.
Conclusion
We have identified keeping one set of URL is important for SEO. Then we have looked at how we can 301 redirect non-www version of URL to www. version URL in ASP.NET MVC. Hope this saves you some time and thank you for being with me so far.
Saturday, May 16, 2009
Recently I have started playing with the Moq (pronounced "Mock-you" or just "Mock") a Mocking Library for .NET Developers, that takes full advantage of .NET 3.5 (i.e. Linq expression trees) and C# 3.0 features. Here in this post I will discuss how I have used the TryUpdateModel method in the Form POST scenario and also share how I have written a test case using Moq mocking library to deal with the TryUpdateModel<TModel>(TModel model) method of the ASP.NET MVC controller.
I have a very simple user interface, that allows user to enter data and submit, to add a new "User".
My View Page is:
and my "Action" is
You may have already noticed that I have decorated my action without any parameters, and my POST related codes are executed by checking the request type.
if (Request.RequestType == POST)
{
//code
}
As I have no parameters in my CreateUser(), I did not need to create separate action with AcceptVerbs("GET") and AcceptVert("POST") attribute. I have created an empty instance of MembershipCreateViewModel object and passed it to the TryUpdateModel() method to get the values of the posted form into my viewmodel object. MVC framework takes care of the rest and populates the viewModel with the desired values. Also note the RedirectToAction() method has been on success, it is very important to perform this client - redirect. It will ensure that the form does not resubmit, and the user will never see a prompt like this, if he hits the browser refresh button.
My MembershipCreateViewModel class is as follows,
I did not prefer passing four parameters to my CreateUser() Action such as,
[AcceptVerbs["POST"])
CreateUser(string username, string email, string password, string confirmPassword)
{
//code
}
instead I kept the method simple by using the MembershipCreateUserViewModel to communicated between the Controller and the View.
This is all good, but by now you may be wondering how would I test this Controller>Action. Lets explore that part. Here I will demonstrate my TestCase using the Moq framework, but you can do the same using other popular mocking frameworks like Rhino Mock, NMock, NMock2, NUnit.Mocks, EasyMock, TypeMock etc, or even with plain vanilla C# code. First of all I will need a FakeHttpContext to interact with my Controller from the test environment.
It is very straight forward to create a mock of a class or interface in Moq, I have created mocks of HttpContextBase, HttpRequestBase, HttpResponseBase, HttpSessionStateBase, HttpServerUtility above and decorated methods and properties that I use in my test cases using the Setup and SetupGet method that is available in the Moq library.
Note how easily with couple of lines of code I have a mockup of the HttpContextBase. The Mock<T> allows creation of custom value matchers that can be used on setups and verification, completely replacing the built-in It class with our own argument matching rules.
var httpContext = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>
httpContext.Setup(ctx => ctx.Request(request.Object);
This above code snippet is creating mock instances of HttpContexBase and HttpRequestBase classes, and then also setting up that httpContext.Request will return the mock instance "request".
Now lets look at how I have used this mock httpContext in a test case.
I have created a test case here that tests our CreateUser() action. Note I have created an instance of the ControllerContext and passed the httpContext mock object as a parameter of its constructor. After that I have assigned this instance ( context ) to the controller.ControllerContext property.
The Mock.Get() method is interesting it can retrieve a mock object for the given object instance. Here I have retrieved the request object and have modified it further. I have setup so that the request.Form returns NameValueCollection. You may be wondering why did I pass NamValueCollection. You may recall that I have used the TryUpdateModel() method in my action to get the form values into our viewmodel, and if you look what is happening under the hood of TryUpdateModel() method you will find that, "Form" is of type System.Collections.Specialized.NameValueCollection and a member of System.Web.HttpRequestBase, and
the internals of TryUpdateModel() iterates through each item of the ContollerContext.HttpContext.Request.Form object and populates the matching properties of the viewmodel using reflection. The above code snippet from the ValueProviderDictionary class where we see that the keys are being read from the Form object to populate a dictionary.
Conclusion
Here in this post I have discussed a Form POST scenario and I have decorated my action method without any parameters as by default TryUpdateModel method looks at the submitted Form object and attempt to assign it to the viewmodel object that we pass. I have also demonstrated how I have used the Moq library to create fake/mock objects for my testcases, how I have setup some fake methods and properties. I have also demonstrated the handy Mock.Get method that can retrieve a mock object from a given object instance and allows us to modify the mock object further. Thank you for being with me so far and I hope this helps.
Saturday, February 14, 2009
Routing Library resides in the System.Web.Routing Namespace of the .NET Framework 3.5, which provides us the flexibility to use URLs that has no mapping to a physical file. This means ASP.NET MVC framework provides flexible URL mapping engine and enables us to write SEO (Search Engine Optimization) friendly URLs with very little effort. No one can deny the importance of SEO, to be successful in search based marketing. What better way to analyze a business than from what customers are looking for on the Internet through keyword research. SEO is the way to go.
SEO friendly URL Format for an e-commerce application may be
/Products/List/ProductCategory
/Products/Detail/ProductName
URL Example
/Products/List/CareCare
/Products/Detail/MiracleCarDuster
In ASP.NET MVC world the URL Routing System maps the incoming URLs to the relevant Controller and Action, in the above example our Contoller is Products and Action is List or Detail. We normally go and define a Route object and add it to the RouteCollection and register the RouteCollection during Application_Start(). Out of the box System.Web.Mvc library ships with the RouteCollectionExtensions which allows us to define routes easily using the the different overloads of MapRoute method.
Example:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
If you look under the hood you will find, a Route object is created and added to the RouteCollection.
Route route = new Route(url, new MvcRouteHandler()){};
.....
.....
routes.Add(name, route);
note that "MvcRouteHandler" have been passed as a parameter by default, when we use the routes.MapRoute() method. The overloads of MapRoute() extension methods are just helper methods to make things easy for us, it is not mandatory that we will have to always use this. We can define a Route object in plain .NET code and assign necessary properties to it, we can also pass our preferred IRouteHandler. This gives superb flexibility with handling URLs. For instance In a practical world of web marketing / search marketing we always need to support Legacy URLs. In the web marketing world ad hoc campaigns are launched, and what may have worked last week may not work this week any more, as a result the URL structure changes frequently and we face the need to start redirecting to the new URLs.
On Top of that during this transformation of URLs we need to implement "301 Moved Permanently" redirections, which means the previous URL has been permanently removed and all future requests should be directed to the given new URI. Handling this scenario has become very easy with the Routing Engine. All we need to do is add a new Route or modify the existing Route to fit our need. Matt Hawley has an excellent post on Legacy Url Routing which describes how to route existing aspx file based URLs to the appropriate MVC Controller and Action. This article also gives directions on how to implement custom Route and custom RouteHandler.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.Add("", new LegacyRoute(
"Users/Login.aspx",
"Login",
new LegacyRouteHandler())); // Defined a Custom Route class and have passed a custom IRouteHandler.
}
As you can see in the above code, how easily we can add a custom route and pass a custom IRouteHandler (in this case LegacyHandler).
Tracking - is another common task performed, we want to track everything, every single clicks a consumer performs on the site. This has also becomes easy in the world of ASP.NET MVC. By design we define separate actions for each functionality and we Route to the Controller - Action to get anything done. So tracking would be a viable option to do centrally just before creating the Controller object or just before delegating to the Action.
You will notice the implementation of IRouteHandler requires to implement only one method "GetHttpHandler" which returns a IHttpHandler
public interface IRouteHandler
{
IHttpHandler GetHttpHandler(RequestContext requestContext);
}
You will find the MvcRouteHandler implements IRouteHandler like this
public class MvcRouteHandler : IRouteHandler {
protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) {
return new MvcHandler(requestContext);
}
}
The real delegation of a Route to a Controller and Action happens in the ProcessRequest(HttpContext context); method of the MVCHandler class which is the implementation of IHttpHandler. The ProcessRequest(HttpContext contxt) method may be a be a good place to centrally control tracking in one of our custom Handlers. The implementaiton of MVCHandler is as follows, where you can see how a controller is created by the IControllerFactory factory, and then Execute() method is called. We can do our tracking somewhere before calling the Execute() method.
protected internal virtual void ProcessRequest(HttpContextBase httpContext) {
AddVersionHeader(httpContext);
// Get the controller type
string controllerName = RequestContext.RouteData.GetRequiredString("controller");
// Instantiate the controller and call Execute
IControllerFactory factory = ControllerBuilder.GetControllerFactory();
IController controller = factory.CreateController(RequestContext, controllerName);
if (controller == null) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentUICulture,
MvcResources.ControllerBuilder_FactoryReturnedNull,
factory.GetType(),
controllerName));
}
try {
controller.Execute(RequestContext);
}
finally {
factory.ReleaseController(controller);
}
}
Did you know, Routes in the ASP.NET Mvc are matched and executed on a first match bases! It may be important to order the routes so that the correct pattern is matched first before a more general pattern matches and executes it. It is sometimes hard to figure out which particular pattern will be caught first when we have a lot of routes, ASP.NET Routing Debugger comes in to rescue, Phil Hack has put together this nice little route tester utility which can save a lot of time. This utility quickly displays in Red and Green color what Route patterns have matched for a particular URL. So we can type in various URLs in the addressbar to see which routes matches.
Lets now looks at a different problem, we normally define all the routes in the global.aspx.cs file, this causes a problem when Routes changes frequently, every single time a new route is added or an existing one is modified we need to recompile web application and upload the new dll to the server, again it is not mandatory to write Routing rules in the global.aspx.cs file, we can easily store the routing rules to a Xml file and use a combination XML related .NET libraries and .NET Reflection APIs to read from the Xml file and create/deserialize Route Objects to add them to the RouteCollection during the Application_Start(). But still we haven't overcome the limitations of restarting the application as the RouteCollection gettting registered during Application_Start. I think we have to live with that, unless we go and implement some kind of FileSystemWatcher to monitor the Xml file and force to refresh the RouteTable.Routes object when the xml file changes. I haven't tried implementing this yet but this would work I think.
We have discussed here, how ASP.NET Routing engine eases writing SEO friendly Url, maitaining Url redirections and tracking centrally. Hope this helps.
Thank you for being with me so far.
Wednesday, February 11, 2009
I normally do not use DataSet and prefer Objects instead generated by the ORM frameworks, but recently I had to produce a ASP.NET page that displayed a list of records from multiple DataTables. Lets look at a similar example.
Lets assume we consume this DataSet which has two DataTables "Agent" and "RealEstateProperty". The task is to display, what properties belongs to which agent, in a GridView.
There are different ways to accomplish this task, lets look at them one by one.
Method 1: Bind DataTables to a single GridView
To bind these multiple DataTables to a single GridView control, we can quickly create a new temporary DataTable, with the required fields and populate the Rows and then bind the new DataTable Rows to the GridView.
The above code is self explanatory, where I have created a temporary DataTable, populated its rows by iterating through the original DataTables and then binded the Grid to the new DataTable.Rows. The interesting piece of code to note here is the row.GetChildRows(), which respects the relationship and automatically returns the related child rows. The aspx part looks like the following, where we have a GridView with three columns.
and the RowDataBound code is
Method 2: Bind DataTables to a nested GridView
If we want to avoid creating temporary dummy DataTable as described in method 1, we can use the technique of nested list control. Now we can do this by using
two GridView, or
two DataList, or
two Repeaters or
a combination of Repeater and GridView, or
a combination of Repeater and DataList, or
a combination of GridView and DataList.
We are going to look at a combination of 2 GridViews here, where one GridView is nested inside another, you can do any of the above combinations. For this case the the aspx code is,
Notice the parent and nested GridViews has different onrowdatabound methods. In this technique the parent grid is binded to the the Agent DataTable Rows and the nested GridView is binded to the child RealEstateProperty DataTable Rows. Here is the code.
Method 3: Convert the DataSet to Objects and then bind to GridView
We can generate csharp class from the dataset schema using Xsd.exe and then bind the GridViews to the objects. I have discussed similar technique in one of my previous blog post, where you will find how we can use the Xsd.exe that ships with the .NET Framework.
Example
C:\temp>xsd propertyDataSet.xsd /l:cs /c
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\temp\propertydatasetclass.cs'.
I also demonstrated a handy DataTableToT() method to assist in converting DataTable to strongly typed object. And when we have the DataTable converted to a stronglytyped object/list/collection it is very easy to bind to the bind to the GridView.
Other Tips
1. DataSet also comes with handy Merge Method, check here, we could have also used this method.
2. When we load a DataSet from xml schema if we do not provide the strongly typed DataSet it will not preserve the Relationship automatically.

Note: The Relations Count = 0;
3. To preserve Relations automatically during a DataSet load from xml, provide strongly typed DataSet. Both of the following methods will automatically preserve the parent child relationship. Also even if you consume them from a webservice client application they will preserve the Relations.
4. DataSet.WriteXml() method serializes the DataSet content and writes XML data.
5. DataSet.WriteXmlSchema() method writes the DataSet structure as XML Schema (xsd file).
Conclusion
We have discussed different techniques to bind multiple DataTables to GridView, we have also discussed some handy tips about the DataSet. Hope this helps.
Sunday, January 11, 2009
All our ASP.NET pages must derive from System.Web.UI.Page class, but we can take the advantage of inheritance and create a Custom Base Class to manage Security, Session, Error Handling and other repetitive custom codes elegantly. We normally go and create a custom base class that derives from System.Web.UI.Page class which looks something like this.
Then we go and inherit our ASP.NET pages from this class. Note: For ASP.NET 2.0 website projects this file needs to be in a separate class library because of its dynamic compilation mechanism. Our ASP.NET page may look like this.
This is good but, we also have the flexibility to use generic classes and enjoy the benefits of generic classes in our ASP.NET pages and do not need to worry about type casting to and from the universal base type Object, moreover the lack of compile time checking in our pages may sometimes lead to some grief, that we can avoid easily.
Lets look at how we can extend our BasePage using Generic Class. Lets create a an ExtendedBasePage.
In the above code we have declared a type parameter T in the angle brackets, which must derive from RealEstateProperty class, and our ExtendedBasePage derives from our previous Basepage. Then we have used T as return type of property "Property". You may be wondering by now where did RealEstateProperty class came from.
Here you can see Land and Apartment derives from RealEstateProperty class, these are all business objects of my fictitious realestate website and I want to access the "this.Property" object from my pages. Lets now create a ASP.NET page that derives from ExtendedBasePage<T>.
Here in this ASP.NET page that derives from ExtendedBasePage<Land> I have passed the "Land" as the type parameter, now this.Property is type safe, we cannot go and write this.Property = new Apartment(), the compiler will throw an exception straightway "Cannot implicitly convert type 'Website.Util.Apartment' to 'Website.Util.Land'". Also notice we do not need to type cast this.Property object to Land to be able to access its public properties.
Here we discussed how we can take advantage of Generic Classes in our ASP.NET custom base pages, hope this helps thank you for being with me so far.
All our ASP.NET pages must derive from System.Web.UI.Page class, but we can take the advantage of inheritance and create a Custom Base Class to manage Security, Session, Error Handling and other repetitive custom codes elegantly. We normally go and create a custom base class that derives from System.Web.UI.Page class which looks something like this.
Then we go and inherit our ASP.NET pages from this class. Note: For ASP.NET 2.0 website projects this file needs to be in a separate class library because of its dynamic compilation mechanism. Our ASP.NET page may look like this.
This is good but, we also have the flexibility to use generic classes and enjoy the benefits of generic classes in our ASP.NET pages and do not need to worry about type casting to and from the universal base type Object, moreover the lack of compile time checking in our pages may sometimes lead to some grief.
Lets look at how we can extend our BasePage using Generic Class. Lets create a an ExtendedBasePage.
In the above code we have declared a type parameter T in the angle brackets, which must derive from RealEstateProperty class, and our ExtendedBasePage derives from our previous Basepage. Then we have used T as return type of property "Property". You may be wondering by now where did RealEstateProperty class came from.
Here you can see Land and Apartment derives from RealEstateProperty class, these are all business objects of my fictitious realestate website and I want to access the "this.Property" object from my pages. Lets now create a ASP.NET page that derives from ExtendedBasePage<T>.
Here in this ASP.NET page that derives from ExtendedBasePage<Land> I have passed the "Land" as the type parameter, now this.Property is type safe, we cannot go and write this.Property = new Apartment(), the compiler will throw an exception straightway "Cannot implicitly convert type 'Website.Util.Apartment' to 'Website.Util.Land'". Also notice we do not need to type cast this.Property object to Land to be able to access its public properties.
Here we discussed how we can take advantage of Generic Classes in our ASP.NET custom base pages, hope this helps thank you for being with me so far.
Thursday, December 11, 2008
ADO.NET Data Services enable applications to expose data as a data service to be consumable via web clients. The data service which can be easily accessible via regular HTTP requests. CRUD operations are performed using HTTP verbs - GET, POST, PUT and DELETE. The data service responses open formats such as JSON and Aop/APP which are idal back-ead for AJAX-style applications, Rick Interactive Applications and other web clients. ADO.NET client libraries and developer tools works with both on premises services created using ADO.NET Data Services and also with hosted CLOUD services.
Some useful links
Data Platform Developer Center - Data Services page Data services conceptual documentation on MSDN Data services API reference documentation on MSDN Data services team blog Data services online forum (a place to ask us your data services related questions) Whitepaper: Using ADO.NET Data Services V1
Technical Articles Overview: ADO.NET Data Services
The ADO.NET Data Services framework consists of a combination of patterns and libraries that enable the creation and consumption of data services for the web. This article will discuss the key elements of the ADO.NET Data Services framework at a high level and the motivation behind its design.
Using ADO.NET Data Services
Learn how to create and use ADO.NET Data Services, and get documentation on the various details around the URI and payload formats.
Expose and Consume Data in a Web Services World
What is a data service? The ADO.NET Data Services framework consists of a combination of patterns and libraries that enable the creation and consumption of data services for the web. This article will discuss exposing and consuming data using Data Services, describing data with the Entity Data Model, and securing your service.
MSDN Reference Documentation
MSDN API Reference Documentation – Server
MSDN API Reference Documentation – Client
ADO.NET Data Services (Silverlight)
Data Services Futures Offline-Enabled Data Services and Desktop Applications
Learn how to create offline-capable applications that have a local replica of their data, how to synchronize that replica with an online data service when a network connection becomes available, and how replicas can be used with the ADO.NET Entity Framework.
Transparent Design Process Design Notes
See the teams feature design notes online and give your comments on the design.
How Do I … Deep Dive Videos Developing Applications Using Data Services
See how to use common libraries and tools when building applications using on premises and/or cloud services (Windows Azure services, SQL Data Services, etc.).
Programming Windows Azure Tables Using Data Services Client Libraries and Tools
Learn how to use the highly scalable, available and durable Windows Azure table storage service. This session presents a deep dive with demos (using ADO.NET Data Services clients & interaction conventions) showing in detail how to work with cloud storage.
Tuesday, December 02, 2008
Now Microsoft Chart controls Add-on for Microsoft Visual Studio 2008 can be used for charting needs.
Prerequisite: Microsoft Visual Studio 2008 SP1 and Microsoft Chart Controls for Microsoft .NET Framework 3.5.
For sample Environment for Microsoft Chart Controls check here. The sample environment contains over 200 samples for both ASP.NET and Windows Forms.
See the following related links:
There are lots of third party Chart Controls available for ASP.NET as well, please check here.
Friday, November 07, 2008
Lets say we want to use reflection to generate a mock test case for this following Nested Class ClientAddress.
When we load an assembly from a disk dynamically, we can use GetType to look up a type defined in the assembly.
Example:
Assembly assembly = Assembly.GetAssembly(typeof(TheClient));
Type type = assembly.GetType("ConsoleApplicationUsePlus.TheClient");
object obj = Activator.CreateInstance(type);
But one point to remember here, to get Assembly.GeType working with nested classes a Plus(+) sign should precede the nested class. To get a parent class and a nested class we have to use
Type.GetType("ParentClass+NestedClass") //Notice the Plus(+) sign.
So in the above example to get ClientAddress we would have to write something like this.
Assembly assembly = Assembly.GetAssembly(typeof(TheClient));
Type type = assembly.GetType("ConsoleApplicationUsePlus.TheClient+ClientAddress"); //Notice the Plus(+) sign.
object obj = Activator.CreateInstance(type);
This is well documented in MSDN and here is the full chart
http://msdn.microsoft.com/en-us/library/aa332510.aspx
To Get An unmanaged pointer to MyType
Use Type.GetType("MyType*")
To Get An unmanaged pointer to a pointer to MyType
Use Type.GetType("MyType**")
To Get A managed pointer or reference to MyType
Use Type.GetType("MyType&"). Note that unlike pointers, references are limited to one level.
To Get A parent class and a nested class
Use Type.GetType("MyParentClass+MyNestedClass")
To Get A one-dimensional array with a lower bound of 0
Use Type.GetType("MyArray[]")
To Get A one-dimensional array with an unknown lower bound
Use Type.GetType("MyArray[*]")
To Get An n-dimensional array
Use A comma (,) inside the brackets a total of n-1 times. For example,System.Object[,,] represents a three-dimensional Object array.
To Get A two-dimensional array's array
Use Type.GetType("MyArray[][]")
To Get A rectangular two-dimensional array with unknown lower bounds
Use Type.GetType("MyArray[*,*]") or Type.GetType("MyArray[,]")
Lets go back to generate our mock test case for the Nested class ClientAddress.
namespace ConsoleApplicationUsePlus
{
class Program
{
static void Main(string[] args)
{
MockHelper generator = new MockHelper();
//Generate mock testcase
generator.Generate();
Console.ReadLine();
}
}
class MockHelper
{
int index = 0;
private void GenerateMock(object obj)
{
DoWork(obj, string.Empty);
}
Dictionary<string, string> keys = new Dictionary<string, string>();
private void DoWork(object obj, string baseInstanceName)
{
Console.WriteLine(obj.GetType().ToString());
index = index + 1;
string instanceName = string.Format("{0}{1}", obj.GetType().Name, index);
Console.WriteLine(String.Format("{0} {1} = new {0}(); ", obj.GetType().Name, instanceName));
keys.Add(baseInstanceName, instanceName);
foreach (System.Reflection.PropertyInfo property in obj.GetType().GetProperties())
{
if (property.PropertyType.Assembly.FullName.Contains("ConsoleApplicationUsePlus"))
{
object propertyInstance = property.GetValue(obj, null);
if (propertyInstance == null)
{
propertyInstance = Activator.CreateInstance(property.PropertyType);
if (property.CanWrite)
property.SetValue(obj, propertyInstance, null);
string baseI = String.Format(@"{0}.{1}", instanceName, property.Name);
DoWork(propertyInstance, baseI);
Console.WriteLine(String.Format(@"{0}.{1} = {2} ;", instanceName, property.Name, keys[baseI]));
}
}
else if (property.PropertyType == typeof(string))
{
Console.WriteLine(String.Format(@"{0}.{1} = {2} ;", instanceName, property.Name, GetRandomString()));
}
}
}
//Entry point
public void Generate()
{
Assembly assembly = Assembly.GetAssembly(typeof(TheClient));
Type type = assembly.GetType("ConsoleApplicationUsePlus.TheClient+ClientAddress"); //Notice the plus sign(+)
object obj = Activator.CreateInstance(type);
GenerateMock(obj);
}
private string GetRandomString()
{
long i = 1;
foreach (byte b in Guid.NewGuid().ToByteArray())
{
i *= ((int)b + 1);
}
return string.Format("{0:x}", i - DateTime.Now.Ticks);
}
}
}
and the output looks like the following.
I have discussed about the MockHelper in one of my earlier post, so not discussing this code again here.
Conclusion
We have looked at the qualified type name of nested classes, also looked at how to use Type.GetType() for various types. The best way to avoid any mistakes on the type name possibly, is to create and instance of the class and to invoke the GetType().ToString() on the instantiated object;
Example :
TheClient.ClientAddress obj = new TheClient.ClientAddress();
Console.WriteLine(obj.GetType().ToString());
Enjoy Coding!!
Saturday, August 23, 2008
Problem
I was facing the following Exception when I was programmatically assigning Selected Value of a DropDownList with the following piece of code.
ListItem item = DropDownListTest.Items.FindByValue("Test");
if (item != null)
item.Selected = true;
Exception Cannot have multiple items selected in a DropDownList.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: Cannot have multiple items selected in a DropDownList.
Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Cannot have multiple items selected in a DropDownList.]
System.Web.UI.WebControls.DropDownList.VerifyMultiSelect() +107
System.Web.UI.WebControls.ListControl.RenderContents(HtmlTextWriter writer) +1825978
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.Control.Render(HtmlTextWriter writer) +7
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
CSSFriendly.WizardAdapter.RenderStep(HtmlTextWriter writer, Wizard wizard) +137
CSSFriendly.WizardAdapter.RenderContents(HtmlTextWriter writer) +93
System.Web.UI.WebControls.Adapters.WebControlAdapter.Render(HtmlTextWriter writer) +23
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +2116097
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.Control.Render(HtmlTextWriter writer) +7
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.UpdatePanel.RenderChildren(HtmlTextWriter writer) +236
Solution
The solution is to remember to call ClearSelection() Method before calling FindByValue("") or FindByText("") Method.
The following piece of code will work fine.
DropDownListTest.ClearSelection();
ListItem item = DropDownListTest.Items.FindByValue("Test");
if (item != null)
item.Selected = true;
I also noticed, I do not get the "Cannot have multiple items" exception when I use SelectedIndex instead. i.e.
DropDownListTest.SelectedIndex = 12;
Hope this saves some of your time. Happy Coding.
Wednesday, August 06, 2008
Filling up Mock objects with random data is possibly one of the most time consuming and boring chapter of writing test cases. Let say we have the following classes and we want to write some mock objects.
Mock Object Code Example
private Client GetMockClient()
{
Client Client1 = new Client();
Client1.FirstName = "Random String 6dc22d70-ad0c-4552-9c86-2925e723a326";
Client1.LastName = "Random String 3e08dc98-495a-4a70-bff4-b7b21489b0d0";
ClientAddress ClientAddress2 = new ClientAddress();
ContactAddress ContactAddress3 = new ContactAddress();
ContactAddress3.Address = "Random String e5957034-893b-4d2c-a29a-5b23e2561c00";
ContactAddress3.Phone = "Random String 8d034e87-ece3-42b8-ae97-35fad1639f41";
ContactAddress3.Mobile = "Random String 73a6abad-3268-4ae4-b01c-1732ab0f5f52";
ClientAddress2.HomeAddress = ContactAddress3;
ContactAddress ContactAddress4 = new ContactAddress();
ContactAddress4.Address = "Random String 117ef00d-f29d-4697-97ae-123a6b56da4f";
ContactAddress4.Phone = "Random String 8e4d0bbe-f470-4438-8940-06d9889e3943";
ContactAddress4.Mobile = "Random String 6f0cba5c-5a88-4e5b-88ae-32a569cffa41";
ClientAddress2.ShippingAddress = ContactAddress4;
Client1.ClientAddress = ClientAddress2;
Misc Misc5 = new Misc();
Misc5.OrderDate = DateTime.Now;
Misc5.Quaitity = 945515547;
Misc5.DeliveryDate = DateTime.Now;
Customer Customer6 = new Customer();
CustomerDemographics CustomerDemographics7 = new CustomerDemographics();
CustomerDemographics7.FirstName = "Random String 9b9542e6-2eb9-4ac8-bbd9-46272c8531b4";
CustomerDemographics7.LastName = "Random String 275ca427-9373-41a7-8249-9a3fd94631bd";
ContactAddress ContactAddress8 = new ContactAddress();
ContactAddress8.Address = "Random String c9d18341-cb7e-4086-ba09-76fd7eb09f71";
ContactAddress8.Phone = "Random String d88849f2-f443-46b1-9d21-3eaed1739696";
ContactAddress8.Mobile = "Random String 984cfe2b-c35e-46f4-8eb1-27342d3e21b2";
CustomerDemographics7.HomeAddress = ContactAddress8;
ContactAddress ContactAddress9 = new ContactAddress();
ContactAddress9.Address = "Random String e67ae73f-8edd-47d1-add0-b1e84ddb6b05";
ContactAddress9.Phone = "Random String 91b8d44e-3718-4cc7-be8a-194d308b8969";
ContactAddress9.Mobile = "Random String a0d19e07-2b80-4f7a-acd2-7a507455c000";
CustomerDemographics7.ShippingAddress = ContactAddress9;
Customer6.CustomerDemographics = CustomerDemographics7;
Misc5.AlternativeCustomer1 = Customer6;
Client1.Misc = Misc5;
return Client1;
}
As you can see we will need to spare significant amount of time to prepare a Mock object for "Client" class. But you will be happy to know that I did not write a single line of the code that I pasted above. Yes, I generated it using Reflection. Let me share that magical piece of code with you which can save you a heaps of time.
The Mock Helper
public class MockHelper
{
public MockHelper()
{
this.MaxDepth = 100;
}
int index = 1;
Dictionary<string, string> keys = new Dictionary<string, string>();
List<string> assemblyList = new List<string>();
StringBuilder codeBuilder = null;
public int MaxIndexValue { get; set; }
public string Generate(object obj)
{
//Assembly List that we are interested in for recursive calls, add according to your need.
assemblyList.Add("SmartDataManagement.Blog");
codeBuilder = new StringBuilder();
GenerateCode(obj, string.Empty);
return codeBuilder.ToString();
}
private void GenerateCode(object obj, string theKey)
{
string instanceName = string.Format("{0}{1}", obj.GetType().Name, index);
codeBuilder.AppendLine(String.Format("{0} {1} = new {0}();", obj.GetType().Name, instanceName));
keys.Add(theKey, instanceName);
//Iterate through the list of Public Properties of the object instance
foreach (System.Reflection.PropertyInfo property in obj.GetType().GetProperties())
{
//Decide to dig deeper, if a PropertyType belongs to the assemblies that we are interested in, we go deep.
if (GoDeeper(property))
{
index = index + 1;
//Avoid infinite Loop situation
if (index < this.MaxIndexValue)
{
object propertyInstance = property.GetValue(obj, null);
if (propertyInstance == null)
{
//Dynamically create Property Instance
propertyInstance = Activator.CreateInstance(property.PropertyType);
if (property.CanWrite)
property.SetValue(obj, propertyInstance, null);
string key = Guid.NewGuid().ToString();
codeBuilder.AppendLine();
//Recursive call
GenerateCode(propertyInstance, key);
codeBuilder.AppendLine(String.Format(@"{0}.{1} = {2};", instanceName, property.Name, keys[key]));
codeBuilder.AppendLine();
}
}
}
else if (property.PropertyType == typeof(string))
{
codeBuilder.AppendLine(String.Format(@"{0}.{1} = ""{2}"";", instanceName, property.Name, GetRandomString()));
}
else if (property.PropertyType == typeof(DateTime))
{
codeBuilder.AppendLine(String.Format(@"{0}.{1} = DateTime.Now;", instanceName, property.Name));
}
else if (property.PropertyType == typeof(int))
{
codeBuilder.AppendLine(String.Format(@"{0}.{1} = {2};", instanceName, property.Name, GetRandomInt()));
}
}
}
private bool GoDeeper(PropertyInfo property)
{
//Dig deeper for interested Assemblies only, Please feel free to extend and put complex logics to serve your purpose.
foreach (string assemblyName in assemblyList)
{
if (property.PropertyType.Assembly.FullName.Contains(assemblyName))
return true;
}
return false;
}
private string GetRandomString()
{
return String.Format("Random String {0}", Guid.NewGuid().ToString());
}
private int GetRandomInt()
{
byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToInt32(buffer, 0);
}
}
The above code is self explanatory, I also commented to give an idea of how this is working, In short, I take an instance of the desired class, iterate through all of its Properties using Reflection and generate desired piece of code. While iterating, I also create property instance as required and loop thorough the properties of the child in a recursive manner until all of them are served. The assemblyList object maintains the list of the assemblies that we are interested in for recursion. Its worth mentioning the above piece of code has limitations, it will not work in the cases where there are circular references of Types for properties, that is why I kept a check for MaxIndexValue to break the infinite loop scenario.
Fig, shows an example of circular references of Types, here Client has Misc property (of Type: Misc), and Misc has AlternativeClient1 property (of Type: Client).
The MockHelper has very simple logic to decide to create dynamic instances and to do recursive calls, it will get stuck within Client and Misc for this example. We can definitely overcome this by putting more complex logics and checks. I wanted to keep it simple and moreover it serves my purpose. Also here I cater with int, string and DateTime only, please feel free to extend to serve your purpose. You will notice I used StringBuilder above to accumulate the generated codes, but I normally use my SmartCodeGenerator and write simple templates for this kind of tricks, SmartCodeGenerator provides a lot more flexibility and comes with robust templating feature for purposes like this.
Usage
MockHelper helper = new MockHelper();
//Your desired class instance
Client client = new Client();
string code = helper.Generate(client);
Its quite simple to use the above helper, just create an instance of the MockHelper, then pass an instance of your desired class, it will return you the mock object code as we have seen above. Infact, the above piece of code can speed you up for any cases where you need to create instances of a class and need to write code to fill all its properties, moreover the generated code can also reduce chances of errors and typos that normally happens when we do it manually.
Thank you for being with me so far, hope this saves you some time, Happy coding :)
Thursday, July 24, 2008
.NET Reflection can be quite handy to transform one object to another, and specially when the target data structure varies a lot. Lets say, a "source party" has a stable Source data structure. But different clients have different requirement and expects to served with data in different format. These clients may pass their object instances in their own format and expect to be served with data in their structure. Let me make up an Example here:
Source Data Structure which is consistent and never changes.
Client 1 wants data to be transformed/served in the following structure
Client 2 wants data to be transformed/served in the following structure
and there may be other N-number of clients with N-number of structures, on which "Source Party" has no control.
The use of .NET Attribute and .NET Reflection can produce a very powerful solution to address this kind of scenario. So instead of writing different transforms for different clients, "source party" can simply ask clients to mark their class properties with custom attributes that the "source party" can understand. When clients mark their classes with custom attributes the "source party" can easily take advantage of .NET Reflection to analyze those objects runtime and can act accordingly.
A .NET Attribute class can be designed to keep track of of the Mapping between the source and target data structure.
The client can mark their class/properties with this custom attribute for the (target -> source) mapping.
As the mapping has been performed, we can take advantage of .NET Reflection to transform/serve data in different structure ( infact any structure - considering mapping is done properly ). Lets look at the following magical piece of code.
public class TransformHelper
{
public Source SourceObject { get; set; }
public object GetTransformedObjectObject(object obj)
{
foreach (PropertyInfo property in obj.GetType().GetProperties())
{
FillObject(property, obj);
}
return obj;
}
private void FillObject(PropertyInfo property, object obj)
{
//Identify Custom attribute
SourceMapAttribute attribute = (SourceMapAttribute)Attribute.GetCustomAttribute(property, typeof(SourceMapAttribute));
if (attribute != null)
{
//Check propertyName
/*Put your desired code and logic here.*/
if (attribute.PropertyName != string.Empty)
{
/*Put your desired code and logic here.
I have simply demonstrated with one attribute property,
you can have as many as you like, and can perform any complex operation you prefer.*/
//Get Source Object Value
object sourceValue = GetSourceValue(attribute.PropertyName);
if (property.CanWrite)
{
//Assign source value to the mapped property
property.SetValue(obj, sourceValue, null);
}
}
Type propertyType = property.PropertyType;
object propertyInstance = property.GetValue(obj, null);
if (propertyInstance == null)
{
//Instantiate when Property is not instantiated
propertyInstance = Activator.CreateInstance(property.PropertyType);
if (property.CanWrite)
property.SetValue(obj, propertyInstance, null);
}
foreach (PropertyInfo info in propertyType.GetProperties())
{
//recursive call
FillObject(info, propertyInstance);
}
}
}
private object GetSourceValue(string propertyName)
{
if (SourceObject == null)
{
SourceDataProvider provider = new SourceDataProvider();
this.SourceObject = provider.GetSource();
}
switch (propertyName)
{
case "FirstName":
return SourceObject.FirstName;
case "LastName":
return SourceObject.LastName;
case "ContactAddress":
return this.SourceObject.ContactAddress;
case "ContactPhone":
return this.SourceObject.ContactPhone;
case "ContactMobile":
return this.SourceObject.ContactMobile;
case "ShippingAddress":
return this.SourceObject.ShippingAddress;
case "ShippingPhone":
return this.SourceObject.ShippingPhone;
case "ShippingMobile":
return this.SourceObject.ShippingMobile;
default:
return string.Empty;
}
}
}
Its worth talking a little bit about the above code snippet, all it does is takes an instance of the target class, uses reflection to loop through all its properties, while doing that identifies the custom attributes, checks for the mapping property and assigns values from the Source. This also creates property instances as required and recursively keeps working until all the properties ( including all descendents ) are checked and served.
Lets look at this Transformer in action.
Serve Client 1:
Here is what we see after transformation.
Serve Client 2:
and here is the result.
In this way we can serve any clients objects in any structure ( considering, mapping is done properly ). You will sure agree with me Transforming one object to another by taking advantage of .NET Attribute and .NET Reflection is quite cool. Thank you for being with me so far, Happy coding :)
Thursday, June 26, 2008
1. Make sure your dynamic controls are Loaded on every postback.
Lets play with a very simple example,
ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
</body>
</html>
C# Code Behind
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
TextBox t = new TextBox();
t.ID = "textBox";
this.PlaceHolder1.Controls.Add(t);
}
}
The above code works fine, but a common mistake is to try to conditionally load dynamic controls, if we tweak the code a little bit you will notice we loose our TextBox after any postback. The following code will not load the TextBox after our first postback.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox t = new TextBox();
t.ID = "textBox";
this.PlaceHolder1.Controls.Add(t);
}
}
}
Its recommended to load the dynamic controls during the Page_Init instead, because we may want to hook up our events with proper handler at an early stage.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
TextBox t = new TextBox();
t.ID = "textBox";
t.TextChanged+=new EventHandler(t_TextChanged);
this.PlaceHolder1.Controls.Add(t);
}
}
2. Do not assigning properties of a dynamic control (viewstate enabled), during Page_Init, it will not be reflected.
Here is scenario of another common mistake, "123" assigned to the Text property during Page_Init,
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
TextBox t = new TextBox();
t.ID = "textBox";
t.Text = "123";
this.PlaceHolder1.Controls.Add(t);
}
}
the above code will not work because, Initialization happens before LoadViewState during the control lifecycle. The value assigned to the properties during Initialization will simply get overwritten by the ViewState values.
3. If you are expecting your ViewState to retain after the postback, always assign same ID to the dynamic control
The following piece of code will not work, as I am assigning a new ID to the dynamic control after each postback. The LoadViewState retrieves previously saved viewstate data using the control ID, as the control ID has changed, it doesn't know anymore what to load, as a result it cannot load previously saved viewstate data any more.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
TextBox t = new TextBox();
t.ID = Guid.NewGuid().ToString();
this.form1.Controls.Add(t);
}
}
Thank you for being with me so far.
Tuesday, June 17, 2008
Introduction
There are many situations where we need to identify if partial rendering is supported in a page, especially when a control uses javascript, to get the control work in partial rendering mode, the script needs to be registered using a ScriptManager Type instead. A classic example will be Validators.
The ASP.NET Page class exposes the Validators property, which is a list of all the IValidator types on the page. A page keeps track of its validators, and registers a javascript array of validators automatically to the page. Example, When we add 3 RequiredFieldValidator in a page the following javascript Array will be automatically generated and added in our page automatically during the page load.
Page_Validators = new Array(document.getElementById("RequiredFieldValidator1"),
document.getElementById("RequiredFieldValidator2"),
document.getElementById("RequiredFieldValidator3"));
The ASP.NET Page also registers couple of other script which eventually hooks up different events ( onclick, onkeypress, onchange, onblur ) to the the target control (ControlToValidate), to some predefined javascript functions that resides in WebUIValidation.js file. So when we add a validator in our Page we also notice the following script is automatically added. [WebUIValidation.js ships with ASP.NET and resides in the following folder "/aspnet_client/system_web/<version>/WebUIValidation.js".]
<script type="text/javascript">
<!--
var Page_ValidationActive = false;
if (typeof(ValidatorOnLoad) == "function") {
ValidatorOnLoad();
}
function ValidatorOnSubmit() {
if (Page_ValidationActive) {
return ValidatorCommonOnSubmit();
}
else {
return true;
}
}
// -->
</script>
ValidatorOnLoad plays the big role of hooking up the the events mentioned above, and here is a code snippet from this function,
for (i = 0; i < Page_Validators.length; i++) {
val = Page_Validators[i];
if (typeof(val.evaluationfunction) == "string") {
eval("val.evaluationfunction = " + val.evaluationfunction + ";");
}
...
if (typeof(val.controltovalidate) == "string") {
ValidatorHookupControlID(val.controltovalidate, val);
}
...
}
keen eyes may have already noticed the val.evaluationfunction property, yes every validators needs to have this property for it to work properly under the ASP.NET validation framework. Custom validators takes advantage of this property to point to custom js functions. Custom validator developers normally use RegisterExpandoAttribute method to register this attribute.
protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (this.RenderUplevel)
{
string clientID = this.ClientID;
Page.ClientScript.RegisterExpandoAttribute(clientID, "evaluationfunction", "EntryValidatorEvaluateIsValid");
}
}
Problem
When I used Update Panel with partial rendering enabled the Page.ClientScript.RegisterExpandoAttribute did not work for me. My validators always stopped working after the first postback, which was performed via partial rendering and triggering. I found the "evaluationfunction" in the javascript to be undefined.
Solution
I started looking under the hood, and soon discovered, that the ASP.NET Validators that ships out of the box, ( eg. RangeValidator, RequiredFieldValidator ) uses a different internal method "AddExpandoAttribute" to register the property. Here is a code snippet from the RangeValidator.
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (base.RenderUplevel)
{
string clientID = this.ClientID;
HtmlTextWriter writer2 = base.EnableLegacyRendering ? writer : null;
base.AddExpandoAttribute(writer2, clientID, "evaluationfunction", "RangeValidatorEvaluateIsValid", false);
...
}
}
and code snippet from BaseValidator, the internal method AddExpandoAttribute.
internal void AddExpandoAttribute(HtmlTextWriter writer, string controlId, string attributeName, string attributeValue, bool encode)
{
AddExpandoAttribute(this, writer, controlId, attributeName, attributeValue, encode);
}
After digging further I realized, AddExpandoAttribute checks the ASP.Page whether partial rendering is supported, then it registers the attribute using ScriptManager instead. I did the same with my validation control and it works for me. Here is the piece of code that solved my problem.
protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (this.RenderUplevel)
{
string clientID = this.ClientID;
if (!this.IsPartialRenderingSupported)
{
Page.ClientScript.RegisterExpandoAttribute(clientID, "evaluationfunction", "EntryValidatorEvaluateIsValid");
}
else
{
Type scriptManagerType = BuildManager.GetType("System.Web.UI.ScriptManager", false);
scriptManagerType.InvokeMember("RegisterExpandoAttribute", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { this, clientID, "evaluationfunction", "QuantityEntryValidatorEvaluateIsValid", false });
}
}
}
Note, the I am first checking whether Partial Rendering is Supported and using the ScriptManager Type to register the property instead.
The following piece of code uses Reflection to figure out whether partial rendering is supported.
internal bool IsPartialRenderingSupported
{
get
{
if (!this.PartialRenderingChecked)
{
Type scriptManagerType = BuildManager.GetType("System.Web.UI.ScriptManager", false);
if (scriptManagerType != null)
{
object obj2 = this.Page.Items[scriptManagerType];
if (obj2 != null)
{
PropertyInfo property = scriptManagerType.GetProperty("SupportsPartialRendering");
if (property != null)
{
object obj3 = property.GetValue(obj2, null);
this.IsPartialRenderingEnabled = (bool)obj3;
}
}
}
this.PartialRenderingChecked = true;
}
return this.IsPartialRenderingEnabled;
}
}
private bool PartialRenderingChecked
{
get
{
object val = ViewState["PartialRenderingChecked"];
if (val != null)
return (bool)val;
return false;
}
set
{
ViewState["PartialRenderingChecked"] = value;
}
}
private bool IsPartialRenderingEnabled
{
get
{
object val = ViewState["IsPartialRenderingEnabled"];
if (val != null)
return (bool)val;
return false;
}
set
{
ViewState["IsPartialRenderingEnabled"] = value;
}
}
Conclusion
The Page.ClientScript.RegisterExpandoAttribute may not work in Partial Rendiring mode, when a postback is performed via triggering,
to get this work we need to determine whether partial rendering is supported and use the ScriptManager Type instead like described above.
Hope this helps, and saves some of your time, Thank you for being with me so far.
Wednesday, June 11, 2008
Declaring a property in C# 3.0 is super easy and super short.
public class Student
{
public string Name { get; set; }
}
yes that's it, the framework will take care of the rest, the private variables will be automatically created and the getter and setter will be automatically implemented.
Here is how we can assign value to an automatic property via the constructor
public class Student
{
public string Name { get; set; }
public Student (string name)
{
this.Name = name;
}
}
And finally, here is how we can declare a Readonly property
public class Student
{
public string Name { get; private set; }
public Student (string name)
{
this.Name = name;
}
}
Hope this helps, Enjoy coding.
Monday, June 09, 2008
WebRequest is the abstract base class for the .NET Framework's request/response model for accessing data from the Internet.
To get content of a website, in .NET 1.0. we used to use WebRequest, which is good and also works asynchronously.
public static string GetContent(string url)
{
System.Net.WebRequest request = System.Net.WebRequest.Create(url);
using (System.Net.WebResponse response = request.GetResponse())
{
using (System.IO.StreamReader reader =new System.IO.StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
}
But in .NET 2.0, we can also use the WebClient class. It can also work asynchronous and works the same as the other one.
public static string GetContent(string url)
{
using (System.Net.WebClient client =new System.Net.WebClient())
{
return client.DownloadString(url);
}
}
We can use any of the above method for web scrapeing in .NET. But the second approach is probably more cleaner.